Convert from Gregorian to Julian calendar [duplicate]

巧了我就是萌 提交于 2019-12-11 09:26:48

问题


I need to create a program that reads dates from a .csv file and convert it so that 13 days are added. I already did that but somehow it does not add the following dates as wished. It also goes over 30 days, which is not supposed to happen for example 2001-12-42.

public static void main(String[] args) throws FileNotFoundException, ParseException {
    File fread = new File("src/daten-greg.csv");
    File fwrite = new File("src/daten-jul.csv");

    Scanner s = new Scanner(fread);
    PrintStream print = new PrintStream(fwrite);

    while(s.hasNext()) {
        String[] line = s.nextLine().split(" ");
        print.println(String.join(" ", Convert(line)));
    }

    s.close();
    print.close();
}

private static String[] Convert(String[] value) throws ParseException {
    for (int i = 0; i < value.length; i+=1)
        value[i] = ToJulianisch(value[i]);

    return value;
}

private static String ToJulianisch(String date) throws ParseException {
    SimpleDateFormat  sdf = new SimpleDateFormat("yyyy-mm-dd");
    Date d = sdf.parse(date);


    Calendar c = Calendar.getInstance();
    c.setTime(d);

    int actDay = c.get(Calendar.DAY_OF_MONTH);
    int actMonth = c.get(Calendar.MONTH) + 1 ;
    int actYear = c.get(Calendar.YEAR);
    actDay -= 13;

    if(actDay - 13 < 1) {
        actMonth -= 1;
        if(actMonth < 1) {
            actMonth = 12;
            actYear -= 1;
        }   
        Calendar k = Calendar.getInstance();
        k.set(Calendar.YEAR, actYear);
        k.set(Calendar.MONTH, actMonth - 1);
        actDay = k.getActualMaximum(Calendar.DAY_OF_MONTH) + actDay;
    }

    return String.format("%s-%s-%s", actYear, actMonth, actDay);
}

回答1:


You are subtracting 13 from actDay twice, first in actDay-=13 and again for if(actDay - 13 < 1). Inside the if block, you then add the value which is less than 14 to the number of days per month, resulting in overflowing the day of month.

If you simply want to subtract 13 days from the given date, you should use c.set(Calendar.DAY_OF_MONTH,actDay-13). This will handle the subtraction correctly inside the Calendar object and you can then use

actDay = c.get(Calendar.DAY_OF_MONTH);
int actMonth = c.get(Calendar.MONTH) + 1 ;
int actYear = c.get(Calendar.YEAR);
return String.format("%s-%s-%s", actYear, actMonth, actDay);



回答2:


About some mistakes in your algorithm, see the answer of Heikki Mäenpää. I have also seen another mistake, namely a wrong pattern "yyyy-mm-dd" where "mm" stands for minutes (use "MM" for months).

But in general, you seem to try to reinvent the wheel. Even the old java.util.Calendar-API has a built-in way for the transformation from a gregorian to a julian calendar date, see my solution which is valid even for any date in the past with respect to cutover.

Your solution is only valid for dates where the distance between gregorian and julian calendar is 13 days (which is not true in the past, at the time of Pope Gregor's reform, there were only 10 days cut off).

public static void main(String[] args) throws ParseException {
  String input = "2017-10-24";
  System.out.println("Old API => " + toJulianisch(input)); // 2017-10-11
}

private static String toJulianisch(String date) throws ParseException {
  SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
  sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
  GregorianCalendar gcal = new GregorianCalendar();
  gcal.setTimeZone(TimeZone.getTimeZone("GMT"));
  gcal.setGregorianChange(new Date(Long.MIN_VALUE));
  sdf.setCalendar(gcal);
  Date d = sdf.parse(date);

  gcal.setGregorianChange(new Date(Long.MAX_VALUE));
  gcal.setTime(d);
  return sdf.format(d);
}

As you can see, the old API-stuff even forces you to set the timezone to a fixed offset to avoid any possible timezone clutter. This is necessary because java.util.Calendar and java.util.Date are not real calendar dates but instants/moments.

Side notice:

I have written a time library (Time4J) which can even handle any historic date equal if it was gregorian or julian (or even swedish), equal when the historic year started (was in most cases not the first of January!) etc. Maybe it is overkill for your problem but I mention it for the case you really want to operate with true historic calendar dates.



来源:https://stackoverflow.com/questions/46906227/convert-from-gregorian-to-julian-calendar

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!