以ISO 8601格式生成昨天日期时间的字符串

时间:2017-05-31 06:56:45

标签: java android date calendar simpledateformat

在Android中,我使用java.util.Calendar以格式yyyy-MM-dd'T'hh:mm:ss'Z'获取昨天的日期。例如,如果今天是31 May 2017,我希望昨天的日期为2017-05-30T00:00:00Z

Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);

// Date End = yesterday
calendar.add(Calendar.DATE, -1);
Date dateEnd = calendar.getTime();

SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ss'Z'");
this.dateEndStr = formatter.format(dateEnd);

我希望输出为2017-05-30T00:00:00Z。但它给了我2017-05-30T12:00:00Z

这里有什么问题? TimeZone是否相关?我的时区是GMT/UTC + 08:00 hour

4 个答案:

答案 0 :(得分:4)

我可能回答的问题比您提出的要多,但现在您已经问过,为什么不采取所有措施呢?我看到你的代码有两三个错误。 another answer中的bowmore已经触及了所有三个,但我认为其中的一些可以更清晰一些:

  1. 是的,第一个也是最严重的是时区相关。您需要决定,并且应该在代码中明确指出您使用的时区。在区域偏移+08:00的时间内将Z作为时区是不正确的。 Z代表Zulu时间,是UTC的另一个名称。
  2. 在您的格式模式中,您应该使用大写df_new一小时。
  3. 原则上你应该更喜欢现代的日期和时间类,但至少这样的情况。有了这些,您将无法使用旧式import pandas as pd # 1. generate dataframes per group to get the boundary within `t0` and `tN` from df_s dataframe, where each dataframe has "group, obs, lifetime, status" columns X (tN - t0 / week) rows filled with 0 values. df_all = pd.concat([df_group1, df_group2]) def do_that(R): found_event_row = df_e.iloc[[R.group]] # check if found_event_row['date'] falls into R['obs'] week # if True, then found how long it's there df_new = df_all.apply(do_that)
  4. 犯下错误

    时区

    时区对您的任务至关重要。您需要在HH中,或者在JVM的当前时区(可以在程序运行时随时更改)中确定昨天的UTC日期(如您所请求的输出所示)。此代码段使用UTC:

    SimpleDateFormat

    刚才运行,结果是

    GMT/UTC + 08:00

    您可以使用更简单的代码:

    ,而不是代码段的最后一行
    this.yesterdayAtStartOfDay = LocalDate.now(ZoneOffset.UTC)
        .minusDays(1)
        .atStartOfDay(ZoneOffset.UTC)
        .format(DateTimeFormatter.ISO_INSTANT);
    

    这会得到相同的结果,因为2017-05-30T00:00:00Z .toString(); 提供了时区Z,其atStartOfDay()方法提供了您请求的ISO 8601字符串。

    如果您希望昨天的日期位于其他时区,则在代码段的第一行(并且只有第一行)使用例如ZonedDateTimetoString()ZoneOffset.ofHours(8)作为时区

    如果您使用的是Java 6或7,要使用现代日期和时间类,您需要获取the ThreeTen-Backport library。尽管在引入外部依赖之前我总是三思而后行,但我还是热情地推荐这一点。

    该后端端口在ThreeTenABP项目中进一步适用于Android。

答案 1 :(得分:3)

这只是您SimpleDateFormat中的一个错误。

您使用hh表示小时数,但会显示上午/下午的一小时。

这些是相关符号(来自SimpleDateFormat

  • H小时(0-23)
  • k小时(1-24)
  • K上午/下午(0-11)小时
  • h上午/下午(1-12)小时

你想要这个:"yyyy-MM-dd'T'HH:mm:ss'Z'"

<强> 备注

您说您的时区是+08:00小时,并且您使用该时区计算日期,但是您将其格式化为好像它在Zulu时区(偏移量为+00:00)< / p>

<强> 奖金

在Java 8中,所有这些日历操作都消失了:

ZonedDateTime yesterday = ZonedDateTime.now().with(ChronoField.NANO_OF_DAY, 0).minusDays(1);
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss'Z'");
dateEndStr = formatter.format(dateEnd);

答案 2 :(得分:0)

要减去天数,您应该使用:

Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.DAY_OF_MONTH, -5);

答案 3 :(得分:0)

cal.add(Calendar.DAY_OF_YEAR, -1);