每次我需要使用Java中的日期和/或时间戳时,我总觉得我做错了什么并花费无数个小时试图找到一种更好的API工作方式,而无需编写我自己的日期和时间实用程序类.这是我遇到的一些烦人的事情:
基于0的月份.我意识到最好的做法是使用Calendar.SEPTEMBER而不是8,但令人讨厌的是8代表9月而不是8月.
获取没有时间戳的日期.我总是需要将日期的时间戳部分归零的实用程序.
我知道我过去还有其他问题,但不记得了.随意在您的回复中添加更多内容.
所以,我的问题是......你使用什么第三方API来简化Java对日期和时间操作的使用,如果有的话?有关使用Joda的任何想法?有人仔细观察JSR-310 Date and Time API吗?
我的实体目前包含java Date属性.我开始经常使用Joda Time进行日期操作和计算.这意味着我不断地将我的日期转换为Joda DateTime对象并再次返回.
所以我想知道,有什么理由我不应该只更改我的实体来存储Joda DateTime对象而不是Java Date对象?
请注意,这些实体是通过Hibernate持久化的.我找到了jodatime-hibernate项目,但我也在Joda邮件列表上读到它与较新版本的hibernate不兼容.它似乎维护得不是很好.
所以我想知道是否最好继续在Date和DateTime之间进行转换,或者是否明智地开始持久化DateTime对象.我担心的是依赖于维护不善的图书馆.
编辑:请注意,我的目标之一是更好地存储时区信息.仅存储日期似乎将日期保存在本地时区.由于我的应用程序可以在全球范围内使用,我也需要知道时区.Joda Time Hibernate似乎也在用户指南中解决了这个问题.
这些是包中的两个字段java.time.temporal:
WeekFields.ISO.weekBasedYear()
ISO-8601定义了除其他两种日期之外的所谓周日期,即通常的日历日期(包括年,月和日)和顺序日期(包括年和日) ).星期日的格式为YYYY-'W'ww-e.w代表一周的年份,e代表数字ISO-星期几.Y代表以周为基础的年份,与日历年相同,但在日历年的开始或结束时除外,因为基于周的年份与最终可能在上一年开始的周周期相关联.有两条规则对于理解星期日的形成非常重要:
乍一看,两个JSR-310字段看起来都是相同的,因为ISO-8601只提到了一种基于周的年份.但是等一下,惊喜.让我们考虑以下代码示例:
LocalDate date1 =
LocalDate.of(2000, 2, 29).with(IsoFields.WEEK_BASED_YEAR, 2014);
System.out.println("IsoFields-Test: " + date1); // output: 2014-03-01
LocalDate date2 =
LocalDate.of(2000, 2, 29).with(WeekFields.ISO.weekBasedYear(), 2014);
System.out.println("WeekFields-Test: " + date2); // output: 2014-02-25
Run Code Online (Sandbox Code Playgroud)
虽然我非常了解第二种变化,但我很惊讶看到第一次约会的不同结果是在其类名中使用"官方"ISO-8601-reference.要解释计算结果:
2000-02-29日期对应于ISO-weekdate-notation中的2000-W09-2,而2014-02-25对应于2014-W09-2,保留了一周中的星期和星期几.到目前为止很好.较小字段的这种保留特性类似于如何更改日历年的规则(在大多数情况下应该保持日历日期中的月份和日期不变).
但结果2014-03-01是什么?这里算法简单地将相应的周日添加了四天,以便考虑字段"日期"(29对25)的差异.我没有找到此行为的任何来源或官方文档.有谁知道我们在哪里可以找到这两个领域之间差异的理由?有关算法行为的任何文档?
更新:
现在,我尝试使用此表达式测试新API的自我一致性,以便找出更好地支持哪两个字段:
System.out.println(
"14 week-based-years later = "
+ LocalDate.of(2000, 2, 29).plus(14, IsoFields.WEEK_BASED_YEARS));
Run Code Online (Sandbox Code Playgroud)
输出是2014-03-01类似于描述的情况IsoFields.WEEK_BASED_YEAR,尽管我仍然发现2014-02-25(= 2014-W09-2)的结果更合乎逻辑.由于此类时间单元也在类中找到,IsoFields因此行为在类中是自洽的IsoFields.看起来像一个没有文档和非直观的"功能".
我使用的版本是:java.runtime.version = 1.8.0-b132
更多测试:
LocalDate d = LocalDate.of(2014, 3, 1); // 2014-W09-6
System.out.println( …Run Code Online (Sandbox Code Playgroud) 我正在使用Joda time(1.6)库并且它使用错误的时区(英国夏令时而不是GMT)继续返回DateTime对象.
我的Windows工作站(运行JDK 1.6.0_16)认为它在GMT中,如果从JDK日期/时间类获得默认时区,则它是正确的(GMT).我在Linux服务器上也有同样的行为.我认为在Joda的时区数据库文件中可能是一个错误,所以我用最新的数据库重建了jar但没有任何变化.
import java.util.TimeZone;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.joda.time.LocalTime;
import org.joda.time.format.DateTimeFormatter;
import org.joda.time.format.ISODateTimeFormat;
public class TimeZoneTest {
public static void main(String[] args) {
DateTimeFormatter timeParser = ISODateTimeFormat.timeParser();
TimeZone timeZone = TimeZone.getDefault();
System.out.println(timeZone.getID()); // "Europe/London"
System.out.println(timeZone.getDisplayName()); // "Greenwich Mean Time"
DateTimeZone defaultTimeZone = DateTimeZone.getDefault();
System.out.println(defaultTimeZone.getID()); //"Europe/London"
System.out.println(defaultTimeZone.getName(0L)); //"British Summer Time"
DateTime currentTime = new DateTime();
DateTimeZone currentZone = currentTime.getZone();
System.out.println(currentZone.getID()); //"Europe/London"
System.out.println(currentZone.getName(0L)); //"British Summer Time"
}
}
Run Code Online (Sandbox Code Playgroud)
通过静态初始化程序进行调试,org.joda.time.DateTimeZone我看到System.getProperty("user.timezone")调用"Europe/London"按预期方式给出.
我创建了两个ZonedDateTime对象,我认为它们应该是相同的:
public static void main(String[] args) {
ZoneId zid = ZoneId.of("America/New_York");
ZoneOffset offset = ZoneOffset.from(LocalDateTime.now().atZone(zid));
ZonedDateTime zdt0 = ZonedDateTime.of(2014, 8, 24, 21, 10, 1, 777000002, offset);
ZonedDateTime zdt1 = ZonedDateTime.of(2014, 8, 24, 21, 10, 1, 777000002, zid);
boolean equals = Objects.equals(zdt0, zdt1);
System.out.println("equals: " + equals);
}
Run Code Online (Sandbox Code Playgroud)
在调试器中,我看到ZonedDateTime 区域的成员类在第一种情况下是java.time.ZoneOffset,在第二种情况下是java.time.ZoneRegion,这使得ZonedDateTime对象不相等.这令人困惑......有什么想法吗?
我正在寻找像Java世界中的Joda-Time这样的库(开源).有那样的图书馆吗?
Joda-Time对计算日期和时间非常有帮助.我可以添加日,周,月,年,也可以轻松转换日期和时间.
我希望有像Joda-Time for PHP这样的库.
编辑:我需要Joda-Time中可用的一些函数,例如daysBetween(计算2日期之间的天数),monthsBetween和weeksBetween ...有些关于add和substract日期的函数可以从PHP本身获得.
我想用joda来解析电子邮件中的日期时间字符串.不幸的是,我得到了各种不同的格式,例如
Wed, 19 Jan 2011 12:52:31 -0600
Wed, 19 Jan 2011 10:15:34 -0800 (PST)
Wed, 19 Jan 2011 20:03:48 +0000 (UTC)
Wed, 19 Jan 2011 17:02:08 -0600 (CST)
Fri, 21 Jan 2011 10:39:55 +0100 (CET)
Fri, 21 Jan 2011 17:50:42 -0500 (EST)
Wed, 06 Apr 2011 15:38:25 GMT
Thu, 7 Apr 2011 11:38:24 +0200
Fri, 8 Apr 2011 05:13:36 -0700 (MST)
20 Apr 2011 03:00:46 -0400
Run Code Online (Sandbox Code Playgroud)
下面的代码捕获了大多数变体但不是全部(例如,当有两个空格而不是一个时,逗号丢失等).它看起来很尴尬.
有更优雅的方式来处理这个问题吗?请指教.
DateTimeParser[] parsers = {
DateTimeFormat.forPattern("E, d MMM y HH:mm:ss Z").getParser(),
DateTimeFormat.forPattern("E, d …Run Code Online (Sandbox Code Playgroud) JodaTime有一个提供Hibernate持久性的库.最近我开始关注Joda-Money并开始看看如何使用hibernate持久保存,我没有看到任何库.
有什么建议?