【问题标题】:How to properly format the date?如何正确格式化日期?
【发布时间】:2012-02-15 07:42:32
【问题描述】:

下面显示的函数返回日期,例如“2010 年 9 月 8 日星期六 00:00 PDT”。但我希望得到以下格式的日期“yyyy-MM-dd HH:mm”。这段代码有什么问题?

String date = "2010-08-25";
String time = "00:00";

同样在一台笔记本电脑中输出,例如23:45 是 11:45。如何准确定义 24 格式?

private static Date date(final String date,final String time) {
       final Calendar calendar = Calendar.getInstance();
       String[] ymd = date.split("-");
       int year = Integer.parseInt(ymd[0]);
       int month = Integer.parseInt(ymd[1]);
       int day = Integer.parseInt(ymd[2]);
       String[] hm = time.split(":");
       int hour = Integer.parseInt(hm[0]);
       int minute = Integer.parseInt(hm[1]);
       calendar.set(Calendar.YEAR,year);
       calendar.set(Calendar.MONTH,month);
       calendar.set(Calendar.DAY_OF_MONTH,day);
       calendar.set(Calendar.HOUR,hour);
       calendar.set(Calendar.MINUTE,minute);
       SimpleDateFormat dateFormat =  new SimpleDateFormat("yyyy-MM-dd HH:mm");
       Date d = calendar.getTime();
       String dateString= dateFormat.format(d);
       Date result = null;
       try {
            result = (Date)dateFormat.parse(dateString);
       } catch (ParseException e) {
            e.printStackTrace();
       }
       return result;
    }

【问题讨论】:

    标签: java date time


    【解决方案1】:

    这段代码有什么问题?

    您似乎期望返回的 Date 对象知道您解析它的格式 - 它没有。这只是一个瞬间。当你想要一个特定格式的日期时,你可以使用SimpleDateFormat.format,就这么简单。 (好吧,或者您使用更好的库,例如Joda Time。)

    Date 值视为int - int 只是一个数字;你没有“十六进制整数”或“十进制整数”......当你想格式化它时你会做出决定。 Date 也是如此。

    (同样,Date 与特定日历、时区或地区无关。它只是一个瞬间。)

    【讨论】:

      【解决方案2】:

      您是如何打印出返回结果的?如果您只是使用System.out.println(date("2010-08-25", "00:00"),那么您可能会得到Sat Sep 8 00:00 PDT 2010,具体取决于您正在运行的机器中当前的日期时间格式设置。但是你可以做的是:

      Date d = date("2010-08-25", "00:00");
      System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm").format(d));
      

      只是好奇你为什么要打扰整个过程,因为你可以通过连接你的初始日期和时间字符串来简单地得到结果。

      【讨论】:

      • 如何在所有笔记本电脑上获得 24 格式?现在取决于 - 有时而不是,例如23:45,我得到 11:45。但我需要 23:45。
      【解决方案3】:

      只需使用SimpleDateFormat

      【讨论】:

      • 如您所见,我正在使用 SimpleDateFormat: SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");日期 d = calendar.getTime(); String dateString= dateFormat.format(d);
      【解决方案4】:

      标准库不支持格式化的Date-Time 对象。

      下面显示的函数返回日期,例如“9 月 8 日星期六 00:00 PDT 2010”。但我希望得到以下格式的日期 "yyyy-MM-dd HH:mm"。

      标准的日期时间类没有任何属性来保存格式信息。即使某些库或自定义类承诺这样做,它也打破了Single Responsibility Principle。 Date-Time 对象应该存储有关日期、时间、时区等的信息,而不是格式。以所需格式表示日期时间对象的唯一方法是使用日期时间解析/格式化类型将其格式化为 String

      • 对于现代日期时间 APIjava.time.format.DateTimeFormatter
      • 对于旧的日期时间 APIjava.text.SimpleDateFormat

      关于java.util.Date

      java.util.Date 对象仅表示自称为“纪元”的标准基准时间(即 1970 年 1 月 1 日 00:00)以来的毫秒数: 00 GMT(或 UTC)。由于它不保存任何时区信息,它的 toString 函数应用 JVM 的时区以返回格式为 EEE MMM dd HH:mm:ss zzz yyyyString,从这个 毫秒 值。要以不同的格式和时区获取java.util.Date 对象的String 表示,您需要使用具有所需格式和适用时区的SimpleDateFormat,例如

      Date date = new Date(); // In your case, it will be Date date = date("2010-08-25", "00:00");
      SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.ENGLISH);
      // sdf.setTimeZone(TimeZone.getTimeZone("America/New_York")); // For a timezone-specific value
      String strDate = sdf.format(date);
      System.out.println(strDate);
      

      您的函数Date date(String, String) 容易出错。

      您可以简单地将日期和时间字符串与分隔符组合,然后使用SimpleDateFormat 来解析组合字符串,例如您可以将它们与空白字符结合起来作为分隔符,以使用上面显示的相同 SimpleDateFormat

      private static Date date(final String date, final String time) throws ParseException {
          return sdf.parse(date + " " + time);
      }
      

      请注意,使用分隔符不是强制性要求,例如您可以使用 sdf.parse(date + time) 进行操作,但为此,您需要将 sdf 的格式更改为 yyyy-MM-ddHH:mm,虽然正确,但可能看起来令人困惑。

      演示:

      import java.text.ParseException;
      import java.text.SimpleDateFormat;
      import java.util.Date;
      import java.util.Locale;
      
      public class Main {
          static final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.ENGLISH);
      
          public static void main(String[] args) throws ParseException {
              Date date = date("2010-08-25", "00:00");
              String strDate = sdf.format(date);
              System.out.println(strDate);
          }
      
          private static Date date(final String date, final String time) throws ParseException {
              return sdf.parse(date + " " + time);
          }
      }
      

      输出:

      2010-08-25 00:00
      

      ONLINE DEMO

      切换到java.time API。

      java.util 日期时间 API 及其格式化 API SimpleDateFormat 已过时且容易出错。建议完全停止使用,改用modern Date-Time API*

      使用现代日期时间 API java.time 的解决方案:

      import java.time.LocalDate;
      import java.time.LocalDateTime;
      import java.time.LocalTime;
      import java.time.format.DateTimeFormatter;
      import java.util.Locale;
      
      public class Main {
          public static void main(String[] args) {
              LocalDateTime ldt = localDateTime("2010-08-25", "00:00");
              // Default format i.e. the value of ldt.toString()
              System.out.println(ldt);
      
              // Custom format
              DateTimeFormatter dtf = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm", Locale.ENGLISH);
              String strDate = dtf.format(ldt);
              System.out.println(strDate);
          }
      
          private static LocalDateTime localDateTime(final String date, final String time) {
              return LocalDateTime.of(LocalDate.parse(date), LocalTime.parse(time));
          }
      }
      

      输出:

      2010-08-25T00:00
      2010-08-25 00:00
      

      ONLINE DEMO

      您一定注意到了,我没有使用DateTimeFormatter 来解析String dateString time。这是因为您的日期和时间字符串符合 ISO 8601 标准。现代日期时间 API 基于 ISO 8601,只要日期时间字符串符合 ISO 8601 标准,就不需要明确使用 DateTimeFormatter 对象。

      Trail: Date Time 了解有关现代日期时间 API 的更多信息。


      * 出于任何原因,如果您必须坚持使用 Java 6 或 Java 7,您可以使用 ThreeTen-Backport,它将大部分 java.time 功能向后移植到 Java 6 和 7 . 如果您正在为一个 Android 项目工作并且您的 Android API 级别仍然不符合 Java-8,请检查 Java 8+ APIs available through desugaringHow to use ThreeTenABP in Android Project

      【讨论】:

        【解决方案5】:

        我很惊讶您在不同的计算机上得到不同的日期输出。理论上,SimpleDateFormat 模式“H”应该以 24 小时格式输出日期。你是晚上 11:45 还是上午 11:45?

        虽然它不应该影响结果,但 SimpleDateFormat 和 Calendar 依赖于区域设置,因此您可以尝试指定要使用的确切区域设置 (Locale.US),看看是否有任何不同。

        作为最后的建议,如果您愿意,您也可以尝试使用Joda-Time 库 (DateTime) 来进行日期操作。它使使用日期对象变得更加容易。

            DateTime date = new DateTime( 1991, 10, 13, 23, 39, 0);
            String dateString = new SimpleDateFormat("yyyy-MM-dd HH:mm").format( date.toDate());
            DateTime newDate = DateTime.parse( dateString, DateTimeFormat.forPattern("yyyy-MM-dd HH:mm"));
        

        【讨论】:

          猜你喜欢
          • 2021-06-05
          • 2013-09-18
          • 2020-01-07
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-11-08
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多