我可以仅使用“java.*” API 导出给定“日期”自 1900 年 1 月 1 日以来的天数吗?
电子表格(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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
这是实现目标的一种非常愚蠢且低效的方法,但它可以用来验证其他技术
This is a pretty dumb and inefficient way of achieving your goal, but it could be used to validate other techniques
这里对 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.
您可以使用
myGcalEarlier.getTimeInMillis()
和myGcalLater.getTimeInMillis()
,然后通过除以天数中的毫秒来转换为天数。 24*60*60*1000。你的第一个设定是错误的。
月份是从 0 开始的 0 表示一月
you may use
myGcalEarlier.getTimeInMillis()
andmyGcalLater.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.
month is 0-based 0 for january
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);