1

我正在使用 Java 6。我们的服务器在东部标准时间 (GMT-5) 上,我正在尝试存储一个应该被解释为这样的值,但我对如何转换它感到困惑。我有

    String dateStr = "1368921600000";       // This is 5/19/2013 00:00:00
    final Calendar cal = Calendar.getInstance();
    cal.setTimeZone(TimeZone.getTimeZone("GMT-5"));
    cal.setTimeInMillis(Long.parseLong(dateStr));
    final java.util.Date dateObj = cal.getTime();
    System.out.println(dateObj.toString());

但现在这会打印出“Sat May 18 19:00:00 CDT 2013”​​(因为我的本地机器在 CDT 上)但我希望结果是“Sat May 18 24:00:00 CDT 2013”​​。如何将日期字符串“1368921600000”解释为 EST 日期?谢谢, - 戴夫

4

4 回答 4

2

1368921600000是时间的一瞬间,同一个瞬间,遍及世界各地。要将其转换为日期和时间,您必须指定想知道那一刻的日期/时间。恰好时间戳是相对于 UTC 的,并且是Sun, 19 May 2013 00:00:00 GMT

如果您想要世界其他地方的这一瞬间(同一瞬间)的时间,您可以像以前一样使用日历并提取各个字段值(例如 HOUR_OF_DAY)。如果您只关心获取文本字符串,则使用 DateFormat 实例,例如 SimpleDateFormat:

DateFormat df = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss z");
df.setTimeZone(TimeZone.getTimeZone("America/New_York"));
String timeOnUSEastCoast = df.format(new Date(1368921600000L));
// will be GMT-5 or GMT-4 depending on DST

在此示例中,输出将是 GMT-4: Sat, 18 May 2013 20:00:00 EDT(不仅时间发生了变化,而且仍然是美国东海岸的前一天)。

如果您想输出 UTC 时间但只是想假装它是 EST,那么告诉 DateFormat 离开文本输出中的时区字段(删除“z”)并随意调用它会更容易,但请理解时间戳值始终为 UTC。

于 2013-05-22T05:02:40.790 回答
1

It is often not necessary to use the Joda Time library to get historically accurate time-zone- and daylight-savings-aware local time mappings, although this is the common go to response for many.

If you have a database of timestamps that require local time conversion, then here are some principles that have served me well:

  • Store date/times (Instants, in the parlance of Joda; Dates, in the parlance of the Java Calendar API) in UTC time. UTC does not care about DST. It does not care about time zones. UTC simply represents a universally representable moment in time. This step alone can save a lot of date/time headaches.

  • Database records should contain TimeZone and/or Locale fields so that mapping from UTC can be performed. Think about your data. Every timestamp in your database does not need time zone information associated with it. Instead, associate the time zone data with a part of your data model that provides appropriate granularity. If your app will only ever be localized in one time zone, then you needn't store this infor at all. In my recent project, I created a Locale table that contains the TZ ID for timestamps in my Encounters table. All other timestamps are subordinate to these records, so it made sense to associate it there.

  • Use the Java API GregorianCalendar to map UTC Dates to local time. And that's all I ever use it for. I almost never use GregorianCalendars to do date arithmetic or other date operations. Here is the paradigm that I've been working with:

    public static void main(String[] args) {
    
    m_GregorianCalendar = new GregorianCalendar(TimeZone.getTimeZone(
        "America/Chicago"));
     Date d = new Date();
     String fmt = "dd-MMM-yyyy @ HH:mm";
     :
     :
     String myDate = mapToLocalTime(d, fmt, gc);
     :
     :
     }
    
     public String mapToLocalTime(Date utc, String format, GregorianCalendar gc) {
    
     gc.setTime(utc);  // this calendar is already timezone aware (constructed
                       // with time zone id (DST too))
    
     SimpleDateFormat sdf = new SimpleDateFormat();
     sdf.setCalendar(gc);               // formatter uses conventions of calendar
     sdf.applyPattern(fmt);             // pattern for formatter
    
     return sdf.format(utc);
     }
    
  • Consider representing timestamps internally in a numeric format (longs, doubles). This greatly simplifies date comparisons and date arithmetic. The only downside is that conversions must be done to format the data into a human recognizable form, but if you use functions for these conversions it need not be a big deal at all.

于 2013-05-22T16:00:07.330 回答
0

使用 anew java.util.SimpleDateFormat(format)java.util.DateFormat.getDateTimeInstance(int,int),然后使用#setTimeZone(timezone)

于 2013-05-20T15:41:53.590 回答
0

当您打印 Date.toString() 时,根本不会考虑日历的时区。在您执行 cal.getTime() 之后,在 Calendar 中设置的任何内容都不再相关。

TimeZone 的默认时区是什么。

因此,在打印日期之前,请将默认时区设置为您要打印的时区,例如:

String dateStr = "1368921600000";       // This is 5/19/2013 00:00:00
final Calendar cal = Calendar.getInstance();
TimeZone gmtZero = TimeZone.getTimeZone("GMT");
cal.setTimeInMillis(Long.parseLong(dateStr));
final java.util.Date dateObj = cal.getTime();
TimeZone.setDefault(gmtZero);
System.out.println(dateObj.toString());

无论您的系统时区如何,这都会以 GMT 打印日期。

之后记得带回原来的默认时区!

于 2013-05-20T15:52:23.533 回答