Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/313.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 分析具有不同时区的日期_Java_Postgresql_Timezone - Fatal编程技术网

Java 分析具有不同时区的日期

Java 分析具有不同时区的日期,java,postgresql,timezone,Java,Postgresql,Timezone,即使在Java工作了大约15年,人们在处理日期和时间的话题上也总是会结结巴巴 情况是这样的:我从某个外部系统获得一个时间戳,作为字符串表示。时间戳的语义是表示UTC日期。必须将此时间戳放入实体中,然后放入时间戳字段中的PostgreSQL数据库中。此外,我需要将与本地时间相同的时间戳(在我的例子中是CEST)放入实体中,然后放入带有时区的时间戳字段中的数据库中 确保无论执行代码的机器的设置如何,时间戳都正确存储在实体中(使用其他UTC时间戳进行一些验证)和数据库中(稍后在报告中使用)的正确方法是

即使在Java工作了大约15年,人们在处理日期和时间的话题上也总是会结结巴巴

情况是这样的:我从某个外部系统获得一个时间戳,作为
字符串
表示。时间戳的语义是表示UTC日期。必须将此时间戳放入实体中,然后放入
时间戳
字段中的PostgreSQL数据库中。此外,我需要将与本地时间相同的时间戳(在我的例子中是CEST)放入实体中,然后放入带有时区的
时间戳字段中的数据库中

确保无论执行代码的机器的设置如何,时间戳都正确存储在实体中(使用其他UTC时间戳进行一些验证)和数据库中(稍后在报告中使用)的正确方法是什么

下面是代码,在我的本地机器上运行良好:

SimpleDateFormat sdfUTC = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS");
sdfUTC.setTimeZone(TimeZone.getTimeZone("UTC"));
Date utcTimestamp = sdfUTC.parse(utcTimestampString);
// getMachinesTimezone is some internal util method giving the TimeZone object of the machines Location
Calendar localTimestamp = new GregorianCalendar(getMachinesTimezone());
localTimestamp.setTimeInMillis(utcTimestamp.getTime());
但是当在服务器上执行相同的代码时,它会导致不同的时间,所以我认为这不是正确的处理方法。有什么建议吗


PS:我在这个论坛上搜索时读到了Joda Time,但在给定的项目中,我无法引入新的库,因为我只更改了一个现有的模块,所以我必须使用标准JDK1.6,我认为您必须在日历对象中设置目标时区。我想是这样的:

Calendar localTimestamp = new GregorianCalendar(TimeZone.getTimeZone("GMT+10"));
localTimestamp.setTimeInMillis(utcTimestamp.getTime());

在另一种情况下,Java为日历实例使用默认的系统时区。

如果我理解正确,您需要在您正在打印的同一数据/日历对象上设置时区。像这样:

private Locale locale = Locale.US;
private static final String[] tzStrings = {
    "America/New_York",
    "America/Chicago",
    "America/Denver",
    "America/Los_Angeles",
};

  Date now = new Date();
  for ( TimeZone z : zones) {
        DateFormat df = new SimpleDateFormat("K:mm a,z", locale);
        df.setTimeZone(z);
        String result = df.format(now);
        System.out.println(result); 
  }
如果我将时区设置为SimpleDateFormat,则工作正常

下面是示例代码

String date="05/19/2008 04:30 AM (EST)";
SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy hh:mm aaa (z)");
TimeZone.setDefault(TimeZone.getTimeZone("PST"));
long millis = sdf.parse(date).getTime();
sdf.setTimeZone(TimeZone.getDefault());
System.out.println(sdf.format(new Date(millis)));

您可以通过下面的示例代码来实现

Date date = new Date();

DateFormat formatter = new SimpleDateFormat("dd MMM yyyy HH:mm:ss z");
formatter.setTimeZone(TimeZone.getTimeZone("CET"));

Date date1 = dateformat.parse(formatter.format(date));

// Set the formatter to use a different timezone
formatter.setTimeZone(TimeZone.getTimeZone("IST"));

Date date2 = dateformat.parse(formatter.format(date)); 
// Prints the date in the IST timezone
//    System.out.println(formatter.format(date));

嗨,Geziesfer,如果你没有得到你想要的答案,考虑在你的本地计算机和服务器上添加你得到的实际结果的几个例子。这将为我们提供更多关于这个问题的背景+一个写得好,整洁,语法正确的问题!在一个数据库中存储同一数据两次似乎很愚蠢database@stew当前位置我不是评判现有系统愚蠢的人,但原因是,稍后生成报告的语句需要直接将utc和本地时间作为输入参数,而不是在该点上计算。似乎应该由您来判断,因为您是实现此功能的人。知道生成报告时可能发生的“计算”数量,保存一个整数add计算是一件愚蠢的差事。如果你问你的老板。“你想让我毫无疑问地做一些愚蠢的事情吗,就因为我让你这么做了”,他真的会说“是吗?”“即使在Java工作了15年,人们也总是在处理日期和时间这个话题上结结巴巴的。”。因为日期、时间和时区的发明可能会让程序员的生活陷入地狱,而Java的日期/时间API则让情况更糟。采用JodaTime而不是标准Java API在某些情况下可能会有所帮助,但在与JDBC之类的东西交互时对您没有好处。好的,我在上面的代码中对其进行了调整-但它在服务器上仍然无法按预期工作。@Geziefer您能告诉我问题何时出现吗。在数据库中还是已经在java中?它似乎正确地存储在数据库中,因为我在调试时已经看到了错误的时间戳。问题是,我不是来自您示例中的日期,而是来自字符串,例如“2012-01-01T12:00:00.000”。现在,当我在UTC的DF上解析它并通过时间戳字段中的JPA实体将其保存在postgreSQL db中时,它会导致错误的时间戳:“2012-01-01 13:00:00”。在GMT中执行的机器。如果我切换到本地时间(CET),它会产生不同的结果。这就是我不明白的地方,因为我有一个给定的字符串,并说它应该格式化为UTC。@BhavikAmbani您是否尝试过像Geziefer提到的那样解析字符串?你的方法对我也不起作用。@BhavikAmbani对不起,我是在讽刺,顺便说一句,我不是原来的海报,所以我无论如何不能接受你的回答。你有没有像Geziefer说的那样,尝试解析字符串而不是使用日期对象?(我很抱歉重复我的话,但你似乎没有彻底阅读这些评论,或者至少你的回答不够详尽。)如果我用你的解决方案这样做,对我来说是行不通的。当我使用Anil Kumar C的答案时,它是有效的。区别在于在DateFormatter中设置时区之前使用TimeZone.setDefault(字符串)。关键是,我不打印它,而是将它持久化。在上面的回答中,我指出了我认为奇怪的地方。我遇到了一个与主题开头类似的问题:我将日期作为字符串,并希望将其解析为utc时区中的日期。使用SimpleDataFormat并通过
sdf.setTimeZone(TimeZone.getTimeZone(“utc”))
将其时区设置为utc是不够的。解析器仍然使用我的本地时间。使用
TimeZone.setDefault(TimeZone.getTimeZone(“UTC”))
的技巧是什么。谢谢你的回答。