JodaTime - 如何以 UTC 获取当前时间
JodaTime - how to get current time in UTC
我想获取 UTC 的当前时间。到目前为止我所做的如下(仅用于测试目的):
DateTime dt = new DateTime();
DateTimeZone tz = DateTimeZone.getDefault();
LocalDateTime nowLocal = new LocalDateTime();
DateTime nowUTC = nowLocal.toDateTime(DateTimeZone.UTC);
Date d1 = nowLocal.toDate();
Date d2 = nowUTC.toDate();
L.d("tz: " + tz.toString());
L.d("local: " + d1.toString());
L.d("utc: " + d2.toString());
d1
是我的当地时间,没关系
d2
是我当地时间+1,但应该是当地时间-1...
我的本地时区是 UTC+1(根据调试输出和此处的列表:https://www.joda.org/joda-time/timezones.html)...
如何正确地从一个时区转换到另一个时区(包括毫秒表示)?
编辑
我需要date/milliseconds...这与正确显示时间无关....
编辑 2
现在,在评论和答案的帮助下,我尝试了以下操作:
DateTimeZone tz = DateTimeZone.getDefault();
DateTime nowLocal = new DateTime();
LocalDateTime nowUTC = nowLocal.withZone(DateTimeZone.UTC).toLocalDateTime();
DateTime nowUTC2 = nowLocal.withZone(DateTimeZone.UTC);
Date dLocal = nowLocal.toDate();
Date dUTC = nowUTC.toDate();
Date dUTC2 = nowUTC2.toDate();
L.d(Temp.class, "------------------------");
L.d(Temp.class, "tz : " + tz.toString());
L.d(Temp.class, "local : " + nowLocal + " | " + dLocal.toString());
L.d(Temp.class, "utc : " + nowUTC + " | " + dUTC.toString()); // <= WORKING SOLUTION
L.d(Temp.class, "utc2 : " + nowUTC2 + " | " + dUTC2.toString());
输出
tz : Europe/Belgrade
local : 2015-01-02T15:31:38.241+01:00 | Fri Jan 02 15:31:38 MEZ 2015
utc : 2015-01-02T14:31:38.241 | Fri Jan 02 14:31:38 MEZ 2015
utc2 : 2015-01-02T14:31:38.241Z | Fri Jan 02 15:31:38 MEZ 2015
我想要的是,本地日期显示 15 点,utc 日期显示 14 点...
目前,这似乎有效...
----- EDIT3 - 最终解决方案-----
希望这是一个很好的解决方案...我想,我尊重我得到的所有小费...
DateTimeZone tz = DateTimeZone.getDefault();
DateTime nowUTC = new DateTime(DateTimeZone.UTC);
DateTime nowLocal = nowUTC.withZone(tz);
// This will generate DIFFERENT Dates!!! As I want it!
Date dLocal = nowLocal.toLocalDateTime().toDate();
Date dUTC = nowUTC.toLocalDateTime().toDate();
L.d("tz : " + tz.toString());
L.d("local : " + nowLocal + " | " + dLocal.toString());
L.d("utc : " + nowUTC + " | " + dUTC.toString());
输出:
tz : Europe/Belgrade
local : 2015-01-03T21:15:35.170+01:00 | Sat Jan 03 21:15:35 MEZ 2015
utc : 2015-01-03T20:15:35.170Z | Sat Jan 03 20:15:35 MEZ 2015
SimpleDateFormat sdf = new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss" );
// or SimpleDateFormat sdf = new SimpleDateFormat( "MM/dd/yyyy KK:mm:ss a Z" );
sdf.setTimeZone( TimeZone.getTimeZone( "UTC" ) );
System.out.println( sdf.format( new Date() )
);
而不是 System.out.println( sdf.format( new Date() ) 输入您的本地日期
从这里开始:http://www.joda.org/joda-time/userguide.html#Changing_TimeZone
// get current moment in default time zone
DateTime dt = new DateTime();
// translate to London local time
DateTime dtLondon = dt.withZone(DateTimeZone.forID("Europe/London"));
The resulting value dtLondon has the same absolute millisecond time, but a different set of field values.
您可以用“Europe/London”代替您想要的时区 (UTC)。参见 this list of proper time zone names。
你让它变得比你需要的复杂得多:
DateTime dt = new DateTime(DateTimeZone.UTC);
根本不需要转换。如果你发现你确实需要转换,你可以使用withZone
。我建议您 避免 通过 LocalDateTime
,但是,这样您可能会因时区转换而丢失信息(两个不同的时刻可能具有相同的本地时间)同一时区,因为时钟返回并重复当地时间。
综上所述,为了可测试性,我个人喜欢使用 Clock
接口,它允许我获取当前时间(例如 Instant
)。然后,您可以使用依赖注入在生产 运行 时注入一个真实的系统时钟,并为测试注入一个带有预设时间的假时钟。 Java 8 的 java.time
包内置了这个想法,顺便说一下。
请尽量听取 Jon Skeets 的建议和意见。这里补充说明。您的 edit-2 包含一个错误:
DateTimeZone tz = DateTimeZone.getDefault();
DateTime nowLocal = new DateTime();
LocalDateTime nowUTC = nowLocal.withZone(DateTimeZone.UTC).toLocalDateTime();
DateTime nowUTC2 = nowLocal.withZone(DateTimeZone.UTC);
Date dLocal = nowLocal.toDate();
Date dUTC = nowUTC.toDate();
Date dUTC2 = nowUTC2.toDate();
如果您在 LocalDateTime
类型的对象 nowUTC
上调用 toDate()
,那么您会得到惊喜 - 请参阅 javadoc。 Joda-Time 声称在 java.util.Date
中使用 the same fields
,就像在 nowUTC
中一样。这是什么意思?让我们来分析一下:
nowUTC.toString()
产生 2015-01-02T14:31:38.241
没有时区(注意最后缺少的 Z),所以它只是一个普通的本地时间戳。根据上下文,我们知道它是在 UTC 中生成的。但是,在下一步中,您可以使用上述方法将其转换为 java.util.Date
。此方法将本地时间戳与系统时区(贝尔格莱德)相结合,保留了字段,因此更改了时间。所以你最终错误地纠正了你的瞬间。你的第二行是错误的。
如果你只想
utc date displays 14 o'clock
那就不要使用 Joda-Time 提供的有问题和误导性的转换方法。请改用具有模式 "EEE MMM dd HH:mm:ss zzz yyyy" 或类似模式的专用格式化程序(Joda-Time 提供 DateTimeFormatter
)。在此格式化程序上设置 UTC 偏移量并打印。完毕。完全放弃对 java.util.Date.toString()
的任何调用。这样,您甚至根本不需要进行任何危险的转换。
您还可以使用静态方法now,这样可读性更好
DateTime.now(DateTimeZone.UTC)
使用这个
DateTime.now().withZone(DateTimeZone.UTC)
如果要格式化,可以使用
DateTime.now().withZone(DateTimeZone.UTC).toString("yyyyMMddHHmmss")
我用这个转换器解决了这个问题
public class DateTimeConverter implements AttributeConverter<DateTime, Date> {
@Override
public Date convertToDatabaseColumn(DateTime attribute) {
return attribute == null ? null
: new Date(attribute
.withZone(DateTimeZone.UTC)
.withZoneRetainFields(DateTimeZone.getDefault())
.getMillis());
}
@Override
public DateTime convertToEntityAttribute(Date dbData) {
return dbData == null ? null
: new DateTime(dbData.getTime())
.withZoneRetainFields(DateTimeZone.UTC)
.withZone(DateTimeZone.getDefault());
}
}
日期存储为 UTC 并使用您当前的时区恢复
我想获取 UTC 的当前时间。到目前为止我所做的如下(仅用于测试目的):
DateTime dt = new DateTime();
DateTimeZone tz = DateTimeZone.getDefault();
LocalDateTime nowLocal = new LocalDateTime();
DateTime nowUTC = nowLocal.toDateTime(DateTimeZone.UTC);
Date d1 = nowLocal.toDate();
Date d2 = nowUTC.toDate();
L.d("tz: " + tz.toString());
L.d("local: " + d1.toString());
L.d("utc: " + d2.toString());
d1
是我的当地时间,没关系d2
是我当地时间+1,但应该是当地时间-1...
我的本地时区是 UTC+1(根据调试输出和此处的列表:https://www.joda.org/joda-time/timezones.html)...
如何正确地从一个时区转换到另一个时区(包括毫秒表示)?
编辑
我需要date/milliseconds...这与正确显示时间无关....
编辑 2
现在,在评论和答案的帮助下,我尝试了以下操作:
DateTimeZone tz = DateTimeZone.getDefault();
DateTime nowLocal = new DateTime();
LocalDateTime nowUTC = nowLocal.withZone(DateTimeZone.UTC).toLocalDateTime();
DateTime nowUTC2 = nowLocal.withZone(DateTimeZone.UTC);
Date dLocal = nowLocal.toDate();
Date dUTC = nowUTC.toDate();
Date dUTC2 = nowUTC2.toDate();
L.d(Temp.class, "------------------------");
L.d(Temp.class, "tz : " + tz.toString());
L.d(Temp.class, "local : " + nowLocal + " | " + dLocal.toString());
L.d(Temp.class, "utc : " + nowUTC + " | " + dUTC.toString()); // <= WORKING SOLUTION
L.d(Temp.class, "utc2 : " + nowUTC2 + " | " + dUTC2.toString());
输出
tz : Europe/Belgrade
local : 2015-01-02T15:31:38.241+01:00 | Fri Jan 02 15:31:38 MEZ 2015
utc : 2015-01-02T14:31:38.241 | Fri Jan 02 14:31:38 MEZ 2015
utc2 : 2015-01-02T14:31:38.241Z | Fri Jan 02 15:31:38 MEZ 2015
我想要的是,本地日期显示 15 点,utc 日期显示 14 点... 目前,这似乎有效...
----- EDIT3 - 最终解决方案-----
希望这是一个很好的解决方案...我想,我尊重我得到的所有小费...
DateTimeZone tz = DateTimeZone.getDefault();
DateTime nowUTC = new DateTime(DateTimeZone.UTC);
DateTime nowLocal = nowUTC.withZone(tz);
// This will generate DIFFERENT Dates!!! As I want it!
Date dLocal = nowLocal.toLocalDateTime().toDate();
Date dUTC = nowUTC.toLocalDateTime().toDate();
L.d("tz : " + tz.toString());
L.d("local : " + nowLocal + " | " + dLocal.toString());
L.d("utc : " + nowUTC + " | " + dUTC.toString());
输出:
tz : Europe/Belgrade
local : 2015-01-03T21:15:35.170+01:00 | Sat Jan 03 21:15:35 MEZ 2015
utc : 2015-01-03T20:15:35.170Z | Sat Jan 03 20:15:35 MEZ 2015
SimpleDateFormat sdf = new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss" );
// or SimpleDateFormat sdf = new SimpleDateFormat( "MM/dd/yyyy KK:mm:ss a Z" );
sdf.setTimeZone( TimeZone.getTimeZone( "UTC" ) );
System.out.println( sdf.format( new Date() )
);
而不是 System.out.println( sdf.format( new Date() ) 输入您的本地日期
从这里开始:http://www.joda.org/joda-time/userguide.html#Changing_TimeZone
// get current moment in default time zone
DateTime dt = new DateTime();
// translate to London local time
DateTime dtLondon = dt.withZone(DateTimeZone.forID("Europe/London"));
The resulting value dtLondon has the same absolute millisecond time, but a different set of field values.
您可以用“Europe/London”代替您想要的时区 (UTC)。参见 this list of proper time zone names。
你让它变得比你需要的复杂得多:
DateTime dt = new DateTime(DateTimeZone.UTC);
根本不需要转换。如果你发现你确实需要转换,你可以使用withZone
。我建议您 避免 通过 LocalDateTime
,但是,这样您可能会因时区转换而丢失信息(两个不同的时刻可能具有相同的本地时间)同一时区,因为时钟返回并重复当地时间。
综上所述,为了可测试性,我个人喜欢使用 Clock
接口,它允许我获取当前时间(例如 Instant
)。然后,您可以使用依赖注入在生产 运行 时注入一个真实的系统时钟,并为测试注入一个带有预设时间的假时钟。 Java 8 的 java.time
包内置了这个想法,顺便说一下。
请尽量听取 Jon Skeets 的建议和意见。这里补充说明。您的 edit-2 包含一个错误:
DateTimeZone tz = DateTimeZone.getDefault();
DateTime nowLocal = new DateTime();
LocalDateTime nowUTC = nowLocal.withZone(DateTimeZone.UTC).toLocalDateTime();
DateTime nowUTC2 = nowLocal.withZone(DateTimeZone.UTC);
Date dLocal = nowLocal.toDate();
Date dUTC = nowUTC.toDate();
Date dUTC2 = nowUTC2.toDate();
如果您在 LocalDateTime
类型的对象 nowUTC
上调用 toDate()
,那么您会得到惊喜 - 请参阅 javadoc。 Joda-Time 声称在 java.util.Date
中使用 the same fields
,就像在 nowUTC
中一样。这是什么意思?让我们来分析一下:
nowUTC.toString()
产生 2015-01-02T14:31:38.241
没有时区(注意最后缺少的 Z),所以它只是一个普通的本地时间戳。根据上下文,我们知道它是在 UTC 中生成的。但是,在下一步中,您可以使用上述方法将其转换为 java.util.Date
。此方法将本地时间戳与系统时区(贝尔格莱德)相结合,保留了字段,因此更改了时间。所以你最终错误地纠正了你的瞬间。你的第二行是错误的。
如果你只想
utc date displays 14 o'clock
那就不要使用 Joda-Time 提供的有问题和误导性的转换方法。请改用具有模式 "EEE MMM dd HH:mm:ss zzz yyyy" 或类似模式的专用格式化程序(Joda-Time 提供 DateTimeFormatter
)。在此格式化程序上设置 UTC 偏移量并打印。完毕。完全放弃对 java.util.Date.toString()
的任何调用。这样,您甚至根本不需要进行任何危险的转换。
您还可以使用静态方法now,这样可读性更好
DateTime.now(DateTimeZone.UTC)
使用这个
DateTime.now().withZone(DateTimeZone.UTC)
如果要格式化,可以使用
DateTime.now().withZone(DateTimeZone.UTC).toString("yyyyMMddHHmmss")
我用这个转换器解决了这个问题
public class DateTimeConverter implements AttributeConverter<DateTime, Date> {
@Override
public Date convertToDatabaseColumn(DateTime attribute) {
return attribute == null ? null
: new Date(attribute
.withZone(DateTimeZone.UTC)
.withZoneRetainFields(DateTimeZone.getDefault())
.getMillis());
}
@Override
public DateTime convertToEntityAttribute(Date dbData) {
return dbData == null ? null
: new DateTime(dbData.getTime())
.withZoneRetainFields(DateTimeZone.UTC)
.withZone(DateTimeZone.getDefault());
}
}
日期存储为 UTC 并使用您当前的时区恢复