【问题标题】:SimpleDateFormatter returns two different time zonesSimpleDateFormat 返回两个不同的时区
【发布时间】:2015-12-22 22:48:32
【问题描述】:

我将这两个字符串作为输入字符串

03/12/16
03/14/16

我制作了一个单个 SimpleDateFormatter 对象来获取这样的日期差异

DateFormat formatter = new SimpleDateFormat("MM/dd/yy",Locale.US);
Date dateChkIn = formatter.parse("03/12/16");
System.out.println("Checkin date at nights check - "+dateChkIn.toString());
Date dateChkOut = formatter.parse("03/14/16");
System.out.println("Checkout date at nights check - "+dateChkOut.toString());
Long numberOfNghtsCalc = ((dateChkOut.getTime() - dateChkIn.getTime()) / 86400000L);
System.out.println("number of nigts calculated - "+ numberOfNghtsCalc);

以下是我在服务器中的输出

Checkin date at nights check - Sat Mar 12 00:00:00 EST 2016
Checkout date at nights check - Mon Mar 14 00:00:00 EDT 2016
number of nigts calculated - 1

预期输出是 计算的 nigts 数 - 2 请注意从格式化程序返回的两个不同的时区

更新: 2016 年 3 月 13 日被视为 DST 更改日期。因此我的计算出错了。 (除以 86400000L)

【问题讨论】:

  • 首先使用 Java 8 的 Time API 或 JodaTime 来计算日期之间的差异......您是否碰巧跨越了夏令时边界?
  • @MadProgrammer 感谢您的评论。但是我的系统使用的是 Java 1.5 。此代码在我的生产环境中。所有这些时间;它工作得很好。突然发生了这种情况。
  • 好吧,Joda-Time 支持 Java 5,但你甚至可以使用 Calendar
  • 尝试在SimpleDateFormat下方添加formatter.setTimeZone(TimeZone.getTimeZone("GMT"));

标签: java datetime time simpledateformat dst


【解决方案1】:

我找到了解决方案。我知道最好的解决方案是使用 Joda Time。但是在现有代码的最小变化的情况下,我认为这种棘手的方式会更好。如果您发现任何缺点,请编辑此答案。

    List<Date> dates = new ArrayList<Date>();
    Calendar calendar = new GregorianCalendar();
    calendar.setTime(dateChkIn);

    Date result = null;
    while (calendar.getTime().before(dateChkOut)){
            result = calendar.getTime();


            dates.add(result);
            calendar.add(Calendar.DATE, 1);
    }
    System.out.println("DAYS CALCULATED BY NEW SOLUTION: " + dates.size());
    newNumberOfNghtsCalc = (long) dates.size();
    dates.clear();

这实际上减少了运行时间!

问题中的代码花费的时间:275000(以纳秒为单位)

新解决方案所用时间:103000

【讨论】:

    【解决方案2】:

    在接下来的 2016 年 3 月 13 日,将美国东部时间的时间更改为美国东部时间。所以SimpleDateFormat 负责这个变化。

    here

    【讨论】:

    • 对不起。我不太了解夏令时。在我们的生产中报告了这个问题。我是否需要进行任何代码级别更改来处理此问题?这是一个非常罕见的场合吗?我应该如何告知我的美国客户?
    • @JudeNiroshan:并不罕见!每年更改 EST -> EDT 时都会遇到同样的问题,反之亦然。如果您使用不同的时区(即欧洲与美洲),您也会遇到同样的问题。
    • 但我的问题是为什么 SimpleDateFomatter 返回两个不同的时区? EST 为 12 日,EDT 为 16 日?
    • @Jude:SimpleDateFormatter 返回相同的时区,但该区域的时区发生变化。所以 SDF 对这种变化是明智的。
    【解决方案3】:

    差异是由夏令时造成的,2016 年的夏令时计划为 2016 年 3 月 13 日。在这里你可以阅读一篇关于EDT and EST的区别的短文。

    【讨论】:

      【解决方案4】:

      java.time

      我建议您使用现代的 java.time 日期时间 API。

      演示:

      import java.time.Duration;
      import java.time.LocalDate;
      import java.time.format.DateTimeFormatter;
      import java.time.temporal.ChronoUnit;
      import java.util.Locale;
      
      public class Main {
          public static void main(String[] args) {
              DateTimeFormatter dtf = DateTimeFormatter.ofPattern("M/d/uu", Locale.ENGLISH);
              LocalDate dateChkIn = LocalDate.parse("03/12/16", dtf);
              LocalDate dateChkOut = LocalDate.parse("03/14/16", dtf);
              long days = ChronoUnit.DAYS.between(dateChkIn, dateChkOut);
              System.out.println(days);
          }
      }
      

      输出:

      2
      

      Trail: Date Time 了解现代日期时间 API。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-12-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-12-14
        • 2021-08-16
        • 2013-04-13
        相关资源
        最近更新 更多