【问题标题】:How create Date Object with values in java如何在java中创建具有值的日期对象
【发布时间】:2014-04-15 02:25:37
【问题描述】:

我需要一个日期对象,日期为 2014-02-11。 我不能这样直接创建,

Date myDate = new Date(2014, 02, 11);

所以我的做法如下,

Calendar myCalendar = new GregorianCalendar(2014, 2, 11);
Date myDate = myCalendar.getTime();

有没有简单的方法在java中创建日期对象?

【问题讨论】:

  • 你的方法有什么不容易的?
  • “有什么简单的方法吗”。是什么让您认为这并不容易?时间和日期比您想象的要复杂得多。有多个日历和多个时区。
  • 一行,Date myDate = new GregorianCalendar(2014, 2, 11).getTime();?
  • 谨防在整数文字中使用前导零,如本问题02 中所示。在 Java 中,这意味着 octal (base-8) number 而不是十进制 (base-10) 数字。
  • 仅供参考,非常麻烦的旧日期时间类,例如 java.util.Datejava.util.Calendarjava.text.SimpleDateFormat 现在是 legacy,被 Java 8 中内置的 java.time 类所取代,之后。见Tutorial by Oracle

标签: java date


【解决方案1】:

我认为最好的方法是使用 SimpleDateFormat 对象。

DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
String dateString = "2014-02-11";
Date dateObject = sdf.parse(dateString); // Handle the ParseException here

【讨论】:

  • Y.. 并且确保永远不要使用 YYYY - 使用 yyyy - 特别是如果使用格式而不是解析反向执行此操作。你会得到一些奇怪的结果!!!见这里:code.sololearn.com/c0EYUAOc92uQ/#java
  • 当我得到这个评论时,我只是浪费了几个小时试图修复输出 - 这就是 YYYY 无法工作的原因......是一周年......不管是什么 - 你会得到一些东西比如 12 月 27 日,这一年将是下一年。例如docs.oracle.com/en/java/javase/12/docs/api/java.base/java/text/…
【解决方案2】:

试试这个

 Calendar cal = Calendar.getInstance();
    Date todayDate = new Date();
    cal.setTime(todayDate);

    // Set time fields to zero
    cal.set(Calendar.HOUR_OF_DAY, 0);
    cal.set(Calendar.MINUTE, 0);
    cal.set(Calendar.SECOND, 0);
    cal.set(Calendar.MILLISECOND, 0);
    todayDate = cal.getTime();

【讨论】:

    【解决方案3】:

    问题:将 2 作为月份传递可能会给您带来意想不到的结果:在日历 API 中,月份是从零开始的。 2 实际上意味着三月。

    我不知道您在寻找什么“简单”的方式,因为我觉得使用日历已经足够简单了。

    记得使用正确的月份常量:

     Date date = new GregorianCalendar(2014, Calendar.FEBRUARY, 11).getTime();
    

    另一种方法是使用 DateFormat,我通常有这样的工具:

     public static Date parseDate(String date) {
         try {
             return new SimpleDateFormat("yyyy-MM-dd").parse(date);
         } catch (ParseException e) {
             return null;
         }
      }
    

    这样我就可以简单地写了

    Date myDate = parseDate("2014-02-14");
    

    我更喜欢另一种选择:不再使用 Java 日期/日历。切换到 JODA 时间或 Java 时间(又名 JSR310,在 JDK 8+ 中可用)。您可以使用LocalDate 表示日期,可以通过

    轻松创建
    LocalDate myDate =LocalDate.parse("2014-02-14");
    // or
    LocalDate myDate2 = new LocalDate(2014, 2, 14);
    // or, in JDK 8+ Time
    LocalDate myDate3 = LocalDate.of(2014, 2, 14);
    

    【讨论】:

    • .toTime() 不存在。应该是.getTime()(见Java Docs
    • 抱歉打错字了。虽然我认为 OP 已经知道正确的调用方法:P
    • 很确定你是对的。但是对于那些(像我一样)每次需要时都必须查找它的人来说,这很烦人。感谢您修复:)
    • return new SimpleDateFormat("yyyy-mm-dd").parse(date) 应该是return new SimpleDateFormat("yyyy-MM-dd").parse(date)
    • 好收获。不知道为什么我会犯这样的错误。修复它
    【解决方案4】:

    tl;博士

    LocalDate.of( 2014 , 2 , 11 )
    

    如果您坚持使用糟糕的旧 java.util.Date 类,请从现代 java.time 类转换。

    java.util.Date                        // Terrible old legacy class, avoid using. Represents a moment in UTC. 
    .from(                                // New conversion method added to old classes for converting between legacy classes and modern classes.
        LocalDate                         // Represents a date-only value, without time-of-day and without time zone.
        .of( 2014 , 2 , 11 )              // Specify year-month-day. Notice sane counting, unlike legacy classes: 2014 means year 2014, 1-12 for Jan-Dec.
        .atStartOfDay(                    // Let java.time determine first moment of the day. May *not* start at 00:00:00 because of anomalies such as Daylight Saving Time (DST).
            ZoneId.of( "Africa/Tunis" )   // Specify time zone as `Continent/Region`, never the 3-4 letter pseudo-zones like `PST`, `EST`, or `IST`. 
        )                                 // Returns a `ZonedDateTime`.
        .toInstant()                      // Adjust from zone to UTC. Returns a `Instant` object, always in UTC by definition.
    )                                     // Returns a legacy `java.util.Date` object. Beware of possible data-loss as any microseconds or nanoseconds in the `Instant` are truncated to milliseconds in this `Date` object.   
    

    详情

    如果您想要“简单”,您应该使用 Java 8 中的新 java.time package,而不是 Java 捆绑的臭名昭著的麻烦 java.util.Date 和 .Calendar 类。

    java.time

    Java 8 中内置的 java.time 框架取代了麻烦的旧 java.util.Date/.Calendar 类。

    仅限日期

    LocalDate 类由 java.time 提供,用于表示没有任何时间或时区的仅日期值。您确实需要时区来确定日期,例如,巴黎的新一天比蒙特利尔更早。 ZoneId 类用于时区。

    ZoneId zoneId = ZoneId.of( "Asia/Singapore" );
    LocalDate today = LocalDate.now( zoneId );
    

    转储到控制台:

    System.out.println ( "today: " + today + " in zone: " + zoneId );
    

    今天:2015-11-26 在区域:亚洲/新加坡

    或者使用工厂方法来指定年月日。

    LocalDate localDate = LocalDate.of( 2014 , Month.FEBRUARY , 11 );
    

    本地日期:2014-02-11

    或者传递一个月份号 1-12 而不是 DayOfWeek 枚举对象。

    LocalDate localDate = LocalDate.of( 2014 , 2 , 11 );
    

    时区

    LocalDate 没有实际意义,除非您将其调整为时区。在 java.time 中,我们应用一个时区来生成一个ZonedDateTime 对象。这也意味着一天中的某个时间,但是什么时间呢?通常在一天中的第一刻是有意义的。您可能认为这意味着时间 00:00:00.000,但由于夏令时 (DST) 和其他异常情况,并非总是如此。我们不是假设那个时间,而是要求 java.time 通过调用atStartOfDay 来确定一天中的第一个时刻。

    continent/region 的格式指定proper time zone name,例如America/MontrealAfrica/CasablancaPacific/Auckland。切勿使用 3-4 个字母的缩写,例如 ESTIST,因为它们不是真正的时区,没有标准化,甚至不是唯一的(!)。

    ZoneId zoneId = ZoneId.of( "Asia/Singapore" );
    ZonedDateTime zdt = localDate.atStartOfDay( zoneId );
    

    zdt: 2014-02-11T00:00+08:00[亚洲/新加坡]

    UTC

    对于后端工作(业务逻辑、数据库、数据存储和交换),我们通常使用UTC 时区。在 java.time 中,Instant 类代表 UTC 时间线上的一个时刻。通过调用toInstant,可以从 ZonedDateTime 中提取 Instant 对象。

    Instant instant = zdt.toInstant();
    

    即时:2014-02-10T16:00:00Z

    转换

    您应该完全避免使用java.util.Date 类。但是,如果您必须与 java.time 尚未更新的旧代码进行互操作,则可以来回转换。寻找添加到旧类的新转换方法。

    java.util.Date d = java.util.from( instant ) ;
    

    ……和……

    Instant instant = d.toInstant() ;
    


    关于java.time

    java.time 框架内置于 Java 8 及更高版本中。这些类取代了麻烦的旧 legacy 日期时间类,例如 java.util.DateCalendarSimpleDateFormat

    要了解更多信息,请参阅Oracle Tutorial。并在 Stack Overflow 上搜索许多示例和解释。规格为JSR 310

    Joda-Time 项目现在位于maintenance mode,建议迁移到java.time 类。

    您可以直接与您的数据库交换 java.time 对象。使用符合JDBC 4.2 或更高版本的JDBC driver。不需要字符串,不需要java.sql.* 类。 Hibernate 5 & JPA 2.2 支持 java.time

    从哪里获取 java.time 类?


    更新:Joda-Time 库现在处于维护模式,并建议迁移到 java.time 类。我将保留此部分以了解历史。

    乔达时间

    一方面,Joda-Time 使用合理的编号,所以二月是 2 而不是 1。另一件事是,Joda-Time DateTime 真正知道其分配的时区,而 java.util.Date 似乎有时区但没有。

    别忘了时区。否则,您将获得 JVM 的默认值。

    DateTimeZone timeZone = DateTimeZone.forID( "Asia/Singapore" );
    DateTime dateTimeSingapore = new DateTime( 2014, 2, 11, 0, 0, timeZone );
    DateTime dateTimeUtc = dateTimeSingapore.withZone( DateTimeZone.UTC );
    
    java.util.Locale locale = new java.util.Locale( "ms", "SG" ); // Language: Bahasa Melayu (?). Country: Singapore.
    String output = DateTimeFormat.forStyle( "FF" ).withLocale( locale ).print( dateTimeSingapore );
    

    转储到控制台...

    System.out.println( "dateTimeSingapore: " + dateTimeSingapore );
    System.out.println( "dateTimeUtc: " + dateTimeUtc );
    System.out.println( "output: " + output );
    

    运行时……

    dateTimeSingapore: 2014-02-11T00:00:00.000+08:00
    dateTimeUtc: 2014-02-10T16:00:00.000Z
    output: Selasa, 2014 Februari 11 00:00:00 SGT
    

    转化

    如果您需要转换为 java.util.Date 以与其他类一起使用...

    java.util.Date date = dateTimeSingapore.toDate();
    

    【讨论】:

    • 只有一条评论。在new DateTime( 2014, 02, 11, 0, 0, timeZone ); 等字段中添加零前缀的做法可能并不可取。虽然它在这种情况下有效,但是如果你传递 0809 作为 int 字面量的前缀,0 表示八进制表示,它不会在 8 月和 9 月编译。它甚至会在 1000 之前的几年内为您提供意想不到的价值,例如new DateTime( 0100, 02, 01, 0, 0, timeZone ); 人们可能认为它是公元 100 年,但实际上它是公元 64 年
    • @AdrianShum 哎呀!我从来不知道像整数文字上的前导零这样的无辜小错字会产生如此讨厌的副作用。谢谢。
    • 亲爱的投票者,请在投票的同时留下批评。
    • “如果你坚持使用糟糕的旧 java.util.Date 类”。许多供应商不提供在 JDK7 之后的 Java 上运行的 tomcat 服务器,所以,虽然我喜欢使用较新的东西,但有些供应商却因为其他一些东西而停留在旧的东西上.....
    • @KimvdLinde 更仔细地重新阅读我的答案。看看子弹。找到“Java SE 6 和 Java SE 7”这两个词。
    【解决方案5】:

    我认为您的日期来自 php 并写入 html (dom) 还是? 我有一个 php 函数来准备所有日期和时间戳。这将返回所需的编队。

    $timeForJS = timeop($datetimeFromDatabase['payedon'], 'js', 'local'); // save 10/12/2016 09:20 on var
    

    这种格式可以用在js上创建新的Date...

    <html>
       <span id="test" data-date="<?php echo $timeForJS; ?>"></span>
       <script>var myDate = new Date( $('#test').attr('data-date') );</script>
    </html>
    

    我要说的是,让你自己的函数来包装,这让你的生活更轻松。 您可以将我的 func 作为示例,但包含在我的 cms 中,您不能一对一复制和粘贴 :)

        function timeop($utcTime, $for, $tz_output = 'system')
    {
        // echo "<br>Current time ( UTC ): ".$wwm->timeop('now', 'db', 'system');
        // echo "<br>Current time (USER): ".$wwm->timeop('now', 'db', 'local');
        // echo "<br>Current time (USER): ".$wwm->timeop('now', 'D d M Y H:i:s', 'local');
        // echo "<br>Current time with user lang (USER): ".$wwm->timeop('now', 'datetimes', 'local');
    
        // echo '<br><br>Calculator test is users timezone difference != 0! Tested with "2014-06-27 07:46:09"<br>';
        // echo "<br>Old time (USER -> UTC): ".$wwm->timeop('2014-06-27 07:46:09', 'db', 'system');
        // echo "<br>Old time (UTC -> USER): ".$wwm->timeop('2014-06-27 07:46:09', 'db', 'local');
    
        /** -- */
        // echo '<br><br>a Time from db if same with user time?<br>';
        // echo "<br>db-time (2019-06-27 07:46:09) time left = ".$wwm->timeleft('2019-06-27 07:46:09', 'max');
        // echo "<br>db-time (2014-06-27 07:46:09) time left = ".$wwm->timeleft('2014-06-27 07:46:09', 'max', 'txt');
    
        /** -- */
        // echo '<br><br>Calculator test with other formats<br>';
        // echo "<br>2014/06/27 07:46:09: ".$wwm->ntimeop('2014/06/27 07:46:09', 'db', 'system');
    
        switch($tz_output){
            case 'system':
                $tz = 'UTC';
                break;
    
            case 'local':
                $tz = $_SESSION['wwm']['sett']['tz'];
                break;
    
            default:
                $tz = $tz_output;
                break;
        }
    
        $date = new DateTime($utcTime,  new DateTimeZone($tz));
    
        if( $tz != 'UTC' ) // Only time converted into different time zone
        {
            // now check at first the difference in seconds
            $offset = $this->tz_offset($tz);
            if( $offset != 0 ){
                $calc = ( $offset >= 0  ) ? 'add' : 'sub';
                // $calc = ( ($_SESSION['wwm']['sett']['tzdiff'] >= 0 AND $tz_output == 'user') OR ($_SESSION['wwm']['sett']['tzdiff'] <= 0 AND $tz_output == 'local') ) ? 'sub' : 'add';
                $offset = ['math' => $calc, 'diff' => abs($offset)];
                $date->$offset['math']( new DateInterval('PT'.$offset['diff'].'S') ); // php >= 5.3 use add() or sub()
            }
        }
    
        // create a individual output
        switch( $for ){
            case 'js':
                $format = 'm/d/Y H:i'; // Timepicker use only this format m/d/Y H:i without seconds // Sett automatical seconds default to 00
                break;
            case 'js:s':
                $format = 'm/d/Y H:i:s'; // Timepicker use only this format m/d/Y H:i:s with Seconds
                break;
            case 'db':
                $format = 'Y-m-d H:i:s'; // Database use only this format Y-m-d H:i:s
                break;
            case 'date':
            case 'datetime':
            case 'datetimes':
                $format = wwmSystem::$languages[$_SESSION['wwm']['sett']['isolang']][$for.'_format']; // language spezific output
                break;
            default:
                $format = $for;
                break;
        }
    
        $output = $date->format( $format );
    
        /** Replacement
         * 
         * D = day short name
         * l = day long name
         * F = month long name
         * M = month short name
         */
        $output = str_replace([
            $date->format('D'),
            $date->format('l'),
            $date->format('F'),
            $date->format('M')
        ],[
            $this->trans('date', $date->format('D')),
            $this->trans('date', $date->format('l')),
            $this->trans('date', $date->format('F')),
            $this->trans('date', $date->format('M'))
        ], $output);
    
        return $output; // $output->getTimestamp();
    }
    

    【讨论】:

    • 你为什么要用 PHP 回答一个 >2 岁的 Java 问题?
    【解决方案6】:
    import java.io.*;
    import java.util.*;
    import java.util.HashMap;
    
    public class Solution 
    {
    
        public static void main(String[] args)
        {
            HashMap<Integer,String> hm = new HashMap<Integer,String>();
            hm.put(1,"SUNDAY");
            hm.put(2,"MONDAY");
            hm.put(3,"TUESDAY");
            hm.put(4,"WEDNESDAY");
            hm.put(5,"THURSDAY");
            hm.put(6,"FRIDAY");
            hm.put(7,"SATURDAY");
            Scanner in = new Scanner(System.in);
            String month = in.next();
            String day = in.next();
            String year = in.next();
    
            String format = year + "/" + month + "/" + day;
            Date date = null;
            try
            {
                SimpleDateFormat formatter = new SimpleDateFormat("yyyy/MM/dd");
                date = formatter.parse(format);
            }
            catch(Exception e){
            }
            Calendar c = Calendar.getInstance();
            c.setTime(date);
            int dayOfWeek = c.get(Calendar.DAY_OF_WEEK);
            System.out.println(hm.get(dayOfWeek));
        }
    }
    

    【讨论】:

    • SimpleDateFormat 格式化程序可用于根据我们格式化日期。然后在 Date 对象中进行解析。上面的程序显示了如何通过给出任何日期来获取工作日。
    【解决方案7】:

    来自Java8:

    import java.time.Instant;
    import java.util.Date;
    
    Date date = Date.from(Instant.parse("2000-01-01T00:00:00.000Z"))
    

    【讨论】:

      【解决方案8】:
      SimpleDateFormat sdf = new SimpleDateFormat("MMM dd yyyy HH:mm:ss", Locale.ENGLISH);
      //format as u want
      
      try {
          String dateStart = "June 14 2018 16:02:37";
          cal.setTime(sdf.parse(dateStart));
          //all done
      } catch (ParseException e) {
          e.printStackTrace();
      }
      

      【讨论】:

      • 可怕的 CalendarSimpleDateFormat 类在几年前被 java.time 类所取代。建议在 2018 年使用它们是糟糕的建议。
      • 这个答案没有解决这个问题的细节。
      • 我认为“API 级别”是指 Android。但这不是特定于 Android 的问题。此外,大部分 java.time 功能都在 ThreeTen-Backport 项目中向后移植到 Java 6 和 7。在 ThreeTenABP 项目中进一步适配 Android。因此,无需使用那些糟糕的遗留日期时间类。 java.time 类要好得多。
      • 感谢您的评论。此库是否提供日期差和时差等功能。
      • 是的。在 Stack Overflow 上搜索有关此主题的许多现有问答。还可以查看 ThreeTen-Extra 项目(未向后移植到早期的 Android)。
      【解决方案9】:

      最简单的方法:

      Date date = Date.valueOf("2000-1-1");
      LocalDate localdate = LocalDate.of(2000,1,1);
      LocalDateTime localDateTime = LocalDateTime.of(2000,1,1,0,0);
      

      【讨论】:

      • 应该避免使用第一个,因为您使用的 java.sql.Date 类设计不佳且早已过时。我建议在第二行中使用LocalDate。我的习惯是LocalDate.of(2000, Month.JANUARY, 1),我觉得读起来比较清楚。
      • 因为答案包含 LocalDate 声明,不仅要求 Date 对象(不推荐使用,有时使用)...
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多