我可以仅使用“java.*” API 导出给定“日期”自 1900 年 1 月 1 日以来的天数吗?

发布于 2024-10-11 20:38:31 字数 1318 浏览 4 评论 0原文

电子表格(MS Excel、Google Apps)将日期表示为自 1900 年 1 月 1 日以来的总天数(可能是 注意 Excel 案例中的 2 月 29 日异常)。好的,除闰年外都是 365 天。但这已经太多算术了。

据推测,java.util.[Gregorian]Calendar 知道所有这些内容。问题是,我不知道如何访问它的知识。

在推测的世界中,人们可能会:

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

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

long days = days2 - days1;

遗憾的是,Calendar.get(Calendar.DAYS_IN_YEAR) 不满足 'mysteryMethod' - 它需要一个 Calendar.DAYS_EVER 字段来做我想做的事。

是否有 API 可以获取以日历天数表示的准确差异?

注释

我确实想要日历日,而不是 86400 秒的日。抛开时区和夏令时问题不谈(感谢@Dipmedeep),需要考虑闰年。 31536000 秒是 365 天。 4 年中有 3 年,我从 1 月 1 日到 1 月 1 日。但在第四年,它只获取从 1 月 1 日到 12 月 31 日的数据,每 4 年就有 1 天的错误!

已经有一个获取日历天数的解决方案。迁移到Java只是一小段代码,并且它得到了想要的答案(尽管我不理解它,因此不信任它)。这个问题专门询问(现在在编辑后更是如此)我是否可以完全避免进行这些计算并将其推迟到 JDK 中的“可信”库。到目前为止我的结论是“不”。

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.JANUARY, 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'.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

恋竹姑娘 2024-10-18 20:38:31

这是实现目标的一种非常愚蠢且低效的方法,但它可以用来验证其他技术

    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);
}

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);
}
在巴黎塔顶看东京樱花 2024-10-18 20:38:31

这里对 java 日期 API 的细节知之甚少,但是如果你能找到一种为你提供 Unix 时间戳的方法,你应该能够弄清楚 - Unix 时间戳是自纪元(1970 年 1 月 1 日,0 :00:00 UTC),所以您需要做的就是找到两个日期的 Unix 时间戳,减去,除以 86400(一天中的秒数)并截掉小数部分。

对于时间点的任何其他线性表示形式也可以执行相同的操作 - 您需要知道的是如何转换为该线性表示形式,以及一天中有多少个单位。

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.

|煩躁 2024-10-18 20:38:31

您可以使用 myGcalEarlier.getTimeInMillis()myGcalLater.getTimeInMillis(),然后通过除以天数中的毫秒来转换为天数。 24*60*60*1000。
你的第一个设定是错误的。

set(int year, int month, int date)

月份是从 0 开始的 0 表示一月

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

月隐月明月朦胧 2024-10-18 20:38:31

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

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

长天 = (lTime2 - lTime1)/(24*60*60*1000);

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);

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文