开发者

Can I derive the number of days since Jan 1 1900 for a given `Date` using just the `java.*` API?

开发者 https://www.devze.com 2023-02-05 07:18 出处:网络
Spreadsheets (MS Excel, Google Apps) represent dates as the number of whole days since Jan 1 1900 (possibly caveat a Feb 29 odditiy in Excel\'s case).OK, so it\'s 365 days except on leap years.But tha

Spreadsheets (MS Excel, Google Apps) represent dates as the number of whole days since Jan 1 1900 (possibly caveat a Feb 29 odditiy in Excel's case). OK, so it's 365 days except on leap years. But that's too much arithmetic already.

Presumably, java.util.[Gregorian]Calendar knows all this stuff. The problem is, I don't know how to access it's knowledge.

In a speculative world, one might:

myGcalEarlier.set(1900, Calendar.JANUAR开发者_运维知识库Y, 1);
myGcalLater.set(new Date());

long days1 = myGcalEarlier.mysteryMethod();
long days2 = myGcalLater.mysteryMethod();

long days = days2 - days1;

Sadly, Calendar.get(Calendar.DAYS_IN_YEAR) doesn't satisfy for 'mysteryMethod' - it would need a Calendar.DAYS_EVER field to do what I want.

Is there an API for getting an accurate difference expressed in calendar days?

Notes

I really do want calendar days, and not days-of-86400-seconds. Time zones and daylight-savings matters aside (thanks @Dipmedeep), leap years need to be considered. 31536000 seconds is 365 days in these terms. 3 out of 4 years, that gets me from Jan 1 to Jan1. But on the 4th year, it only gets me from Jan 1 to Dec 31, giving me a 1-day error for every 4 years!

I already have a solution for getting the number of calendar days. It's a trivial bit of code to migrate to Java, and it gets the desired answer (although I don't understand it, and therefore distrust it). This question is specifically asking (now even moreso after editing) if I can at all avoid doing those calculations and defer it to a 'trusted' library in the JDK. I have thus far concluded 'no'.


This is a pretty dumb and inefficient way of achieving your goal, but it could be used to validate other techniques

    public static void main(String[] args) {
      Calendar now = Calendar.getInstance();
      //now.setTime(new Date()); // set the date you want to calculate the days for
      Calendar tmp = Calendar.getInstance();
      tmp.set(0,0,0); // init a temporary calendar.
      int days=0;
      // iterate from 1900 and check how many days are in the year, sum the days 
      for (int i=1900; i < now.get(Calendar.YEAR);i++) {
          tmp.set(Calendar.YEAR, i);
          int daysForThatYear = tmp.getActualMaximum(Calendar.DAY_OF_YEAR);
          days+=daysForThatYear;
          System.out.printf("year:%4d days in the year:%3d, total days:%6d\n",i,daysForThatYear,days);
      }
      // check the number of days for the current year, and add to the total of days
      int daysThisYear = now.get(Calendar.DAY_OF_YEAR);
      days+=daysThisYear;
      System.out.printf("year:%4d days in the year:%3d, total days:%6d\n",now.get(Calendar.YEAR),daysThisYear,days);
}


Little knowledge about the specifics of java's date API here, but if you can find a method that gives you Unix timestamps, you should be able to figure it out - a Unix timestamp is the number of seconds since epoch (Jan 1st, 1970, 0:00:00 UTC), so all you need to do is find the Unix timestamps for both dates, subtract, divide by 86400 (the number of seconds in a day) and cut off the fractional part.

The same can be done for any other linear representation of the time points - all you need to know is how to convert to that linear representation, and how many units there are in a day.


you may use myGcalEarlier.getTimeInMillis() and myGcalLater.getTimeInMillis() and then convert to days by dividing on milliseconds in a day count. 24*60*60*1000. and your first set call is wrong.

set(int year, int month, int date)

month is 0-based 0 for january


GregorianCalendar myGcalEarlier = new GregorianCalendar(); GregorianCalendar myGcalLater = new GregorianCalendar(); myGcalEarlier.set(1900, Calendar.JANUARY, 1);

long lTime1 = myGcalEarlier.getTimeInMillis(); long lTime2 = myGcalLater.getTimeInMillis();

long days = (lTime2 - lTime1)/(24*60*60*1000);

0

精彩评论

暂无评论...
验证码 换一张
取 消