Java JodaTime - 如何在 UTC 中获取当前时间
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/27741288/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
JodaTime - how to get current time in UTC
提问by prom85
I want to get the current time in UTC. What I do so far is following (just for testing purposes):
我想以 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
is my local time, that's fined2
is my local time + 1, but should be local time - 1...
d1
这是我的当地时间,没关系d2
是我的当地时间 + 1,但应该是当地时间 - 1 ...
My local time zone is UTC+1 (according to the debug output and the list here: https://www.joda.org/joda-time/timezones.html)...
我的本地时区是 UTC+1(根据调试输出和这里的列表:https: //www.joda.org/joda-time/timezones.html)...
How do I correctly convert from one time zone to another (inclusive the millisecond representation)?
如何正确地从一个时区转换为另一个时区(包括毫秒表示)?
EDIT
编辑
I need the date/milliseconds... It's NOT about displaying the time correctly....
我需要日期/毫秒...这与正确显示时间无关....
EDIT 2
编辑 2
Now, with the help of a comment and an answer, I tried following:
现在,在评论和答案的帮助下,我尝试了以下操作:
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());
OUTPUT
输出
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
What I wanted was, that the local date displays 15 o'clock and utc date displays 14 o'clock... For now, this seems to work...
我想要的是,本地日期显示 15 点钟,UTC 日期显示 14 点钟......现在,这似乎有效......
----- EDIT3 - Final solution -----
----- EDIT3 - 最终解决方案 -----
Hopefully, this is a good solution... I think, i respects all tipps i got...
希望这是一个很好的解决方案......我想,我尊重我得到的所有提示......
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());
Output:
输出:
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
采纳答案by Jon Skeet
You're making it far more complicated than you need to:
你让它变得比你需要的复杂得多:
DateTime dt = new DateTime(DateTimeZone.UTC);
No conversionrequired at all. If you find you actually need to convert, you can use withZone
. I'd suggest you avoidgoing via LocalDateTime
, however, as that way you can lose information due to time zone transitions (two different instants can have the same local time in the same time zone, because clocks go back and repeat local time.
根本不需要转换。如果您发现确实需要转换,则可以使用withZone
. 但是,我建议您避免通过 via LocalDateTime
,因为那样您可能会因时区转换而丢失信息(两个不同的时刻可以在同一时区具有相同的本地时间,因为时钟会返回并重复本地时间。
Having said all of this, for the sake of testability I personally like using a Clock
interface which allows me to get the current time (e.g. as an Instant
). You can then use dependency injection to inject a real system clock when running in production, and a fake clock with a preset time for tests. Java 8's java.time
package has this idea built into it, btw.
说了这么多,为了可测试性,我个人喜欢使用Clock
允许我获取当前时间的接口(例如作为Instant
)。然后,您可以使用依赖注入在生产中运行时注入一个真实的系统时钟,以及一个具有预设时间的假时钟进行测试。Java 8 的java.time
包内置了这个想法,顺便说一句。
回答by LONGHORN007
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() )
);
Instead of System.out.println( sdf.format( new Date() ) put your local date
而不是 System.out.println( sdf.format( new Date() ) 把你的本地日期
回答by Greg Kopff
From here: http://www.joda.org/joda-time/userguide.html#Changing_TimeZone
从这里: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.
结果值 dtLondon 具有相同的绝对毫秒时间,但一组不同的字段值。
You can substitute `Europe/London' for the timezone you want (UTC). See this list of proper time zone names.
您可以将“欧洲/伦敦”替换为您想要的时区 (UTC)。请参阅此正确时区名称列表。
回答by Meno Hochschild
Please try to listen to Jon Skeets good advise and comments. Here an additional explanation. Your edit-2 contains a mistake:
请尽量听取 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();
If you call toDate()
on an object nowUTC
of type LocalDateTime
then you can get surprises - see javadoc. Joda-Time claims to use the same fields
in java.util.Date
as in nowUTC
. What does this mean? Let's analyze:
如果你调用toDate()
一个nowUTC
类型的对象,LocalDateTime
那么你会得到惊喜 - 请参阅javadoc。Joda-Time 声称使用the same fields
in java.util.Date
as in nowUTC
。这是什么意思?我们来分析一下:
nowUTC.toString()
produces 2015-01-02T14:31:38.241
That is without timezone (note the missing Z at the end), so it is just a plain local timestamp. By context, we know it was generated in UTC. In your next step however, you convert it to a java.util.Date
using the mentioned method above. This method combines the local timestamp with the system timezone (Belgrade) PRESERVING the FIELDS, hence CHANGING the instant. So you have finally miscorrected your instant. And your second line is wrong.
nowUTC.toString()
产生2015-01-02T14:31:38.241
那是没有时区的(注意最后缺少的 Z),所以它只是一个普通的本地时间戳。根据上下文,我们知道它是在 UTC 中生成的。但是,在下一步中,您将java.util.Date
使用上述方法将其转换为 a 。此方法将本地时间戳与系统时区(贝尔格莱德)相结合,保留字段,从而更改瞬间。所以你终于错误地纠正了你的瞬间。你的第二行是错误的。
If you just want
如果你只是想要
utc date displays 14 o'clock
UTC 日期显示 14 点钟
then don't use the questionable and misleading conversion method Joda-Time offers. Use instead a dedicated formatter with the pattern "EEE MMM dd HH:mm:ss zzz yyyy" or similar (Joda-Time offers DateTimeFormatter
). Set the UTC-offset on this formatter and print. Done. Abandon completely any call of java.util.Date.toString()
. This way, you don't even need to do any dangerous conversion at all.
然后不要使用 Joda-Time 提供的有问题和误导性的转换方法。使用具有“EEE MMM dd HH:mm:ss zzz yyyy”或类似模式的专用格式化程序(Joda-Time 提供DateTimeFormatter
)。在此格式化程序上设置 UTC 偏移量并打印。完毕。完全放弃任何调用java.util.Date.toString()
。这样,您甚至根本不需要进行任何危险的转换。
回答by Kobynet
回答by Naidu
Use this
用这个
DateTime.now().withZone(DateTimeZone.UTC)
and if you want to format, you can use
如果你想格式化,你可以使用
DateTime.now().withZone(DateTimeZone.UTC).toString("yyyyMMddHHmmss")
回答by Wicowyn
I fixed this with this converter
我用这个转换器解决了这个问题
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());
}
}
Dates are stored as UTC and recovered with your current time zone
日期存储为 UTC 并使用您当前的时区恢复