Java에서 값으로 날짜 객체를 만드는 방법


91

2014-02-11 날짜에 대한 날짜 개체가 필요합니다. 이렇게 직접 만들 수는 없지만

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

그래서 저는 다음과 같이하고 있습니다.

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

자바에서 날짜 객체를 만드는 쉬운 방법이 있습니까?


7
접근 방식에서 쉽지 않은 것은 무엇입니까?
giorashc

3
"쉬운 방법이 있습니까?" 그렇게 쉬운 일이 아니라고 생각하는 이유는 무엇입니까? 시간과 날짜는 생각보다 훨씬 더 복잡합니다. 여러 캘린더와 여러 시간대가 있습니다.
Raedwald 2014 년

5
한 줄은 Date myDate = new GregorianCalendar(2014, 2, 11).getTime();?
Elliott Frisch 2014 년

2
이 질문에서 볼 수 있듯이 정수 리터럴에서 선행 0을 사용하지 않도록주의하십시오 02. Java에서는 10 진수 (밑수 10)가 아닌 8 진수 (밑수 8) 숫자 를 의미합니다 .
Basil Bourque 2015

2
참고로, 같은 몹시 귀찮은 된 날짜 - 시간 수업 java.util.Date, java.util.Calendar그리고 java.text.SimpleDateFormat지금 기존 에 의해 대체, java.time의 나중에 자바 8에 내장 된 클래스. Oracle의 Tutorial 참조하십시오 .
Basil Bourque

답변:


108

Gotcha : 2를 월로 전달하면 예기치 않은 결과가 발생할 수 있습니다. Calendar API에서 월은 0부터 시작합니다. 2는 실제로 3 월을 의미합니다.

캘린더를 사용하는 것이 이미 충분히 쉽다고 느끼기 때문에 찾고있는 "쉬운"방법이 무엇인지 모르겠습니다.

월에 올바른 상수를 사용해야합니다.

 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 Date / Calendar를 사용하지 마십시오. JODA 시간 또는 Java 시간 (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);

1
.toTime()존재하지 않습니다. 그것은해야한다 .getTime()(참조 자바 문서를 )
0xJoKe

오타로 죄송합니다. OP는 이미 올바른 호출 방법을 알고 있다고 생각하지만 : P
Adrian Shum

당신이 옳다고 확신합니다. 그러나 필요할 때마다 찾아야하는 (나와 같은) 사람들에게는 성가신 일입니다.
고쳐

1
return new SimpleDateFormat("yyyy-mm-dd").parse(date) 이어야합니다return new SimpleDateFormat("yyyy-MM-dd").parse(date)
aks

잘 잡았습니다. 내가 왜 그런 실수를했는지 Dunno. 문제 해결
Adrian Shum

34

tl; dr

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와 함께 번들로 제공되는 악명 높은 java.util.Date 및 .Calendar 클래스 대신 Java 8 의 새로운 java.time 패키지사용해야합니다 .

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 );

localDate : 2014-02-11

또는 DayOfWeek열거 형 개체가 아닌 월 번호 1-12를 전달 합니다.

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

시간대

여기에 이미지 설명 입력

A LocalDate는 시간대로 조정할 때까지 실제 의미가 없습니다. java.time에서는 ZonedDateTime객체 를 생성하기 위해 시간대를 적용 합니다. 그것은 또한 하루 중 시간을 의미하지만 몇시입니까? 일반적으로 하루 중 첫 번째 순간으로 이동하는 것이 좋습니다. 시간을 의미한다고 생각할 수 00:00:00.000있지만 DST (일광 절약 시간) 및 기타 이상 현상 때문에 항상 사실은 아닙니다. 그 시간을 가정하는 대신, 우리는을 호출하여 하루의 첫 순간을 결정하도록 java.time을 요청 atStartOfDay합니다.

지정 적절한 시간대 이름 의 형식 continent/region예컨대, America/Montreal, Africa/Casablanca, 또는 Pacific/Auckland. 절대로 같은 3-4 문자 약어를 사용하지 EST또는 IST있는 그대로 하지 진정한 시간대가 아닌 표준화, 심지어 고유하지 않은 (!).

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

zdt : 2014-02-11T00 : 00 + 08 : 00 [아시아 / 싱가포르]

UTC

여기에 이미지 설명 입력

백엔드 작업 (비즈니스 로직, 데이터베이스, 데이터 저장 및 교환)의 경우 일반적으로 UTC 시간대를 사용 합니다. java.time에서 Instant클래스는 UTC로 타임 라인의 순간을 나타냅니다. Instant 객체는를 호출하여 ZonedDateTime에서 추출 할 수 있습니다 toInstant.

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의 모든 날짜-시간 유형 표


java.time 정보

java.time의 프레임 워크는 나중에 자바 8에 내장되어 있습니다. 이 클래스는 까다로운 기존에 대신 기존 과 같은 날짜 - 시간의 수업을 java.util.Date, Calendar, SimpleDateFormat.

자세한 내용은 Oracle Tutorial을 참조하십시오 . 그리고 많은 예제와 설명을 위해 Stack Overflow를 검색하십시오. 사양은 JSR 310 입니다.

Joda 타임 프로젝트는 지금에 유지 관리 모드 의로 마이그레이션을 조언 java.time의 클래스.

java.time 객체를 데이터베이스와 직접 교환 할 수 있습니다 . JDBC 4.2 이상을 준수 하는 JDBC 드라이버를 사용하십시오 . 문자열이나 클래스 가 필요하지 않습니다 . Hibernate 5 및 JPA 2.2는 java.time을 지원 합니다 .java.sql.*

java.time 클래스는 어디서 구할 수 있습니까?


업데이트 : Joda-Time 라이브러리는 이제 유지 관리 모드에 있으며 java.time 클래스 로의 마이그레이션을 권장 합니다. 나는 역사를 위해이 섹션을 남겨두고있다.

Joda-Time

2 월은 그래서 우선, Joda 타임은 합리적인 번호를 사용 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();

4
하나의 댓글입니다. 같은 필드에 접두사 0을 붙이는 연습 new DateTime( 2014, 02, 11, 0, 0, timeZone );은 아마도 바람직하지 않을 것입니다. 그것은이 경우에 작동하지만,하지만, 그것은 8 월과 9 월이 통과하는 경우에 대해 컴파일되지 않습니다 08090 수단 진수 프리젠 테이션이있는 int 문자를 접두어로. 심지어 년 전에 당신에게 예상치 못한 값을 줄 것이다 1000예를 들어, new DateTime( 0100, 02, 01, 0, 0, timeZone );하나는 100AD 될 것으로 기대 수도 있지만, 실제로는 64AD입니다
아드리안 셤

트윗 담아 가기 정수 리터럴의 선행 0과 같은 무고한 작은 오타가 그렇게 불쾌한 부작용을 일으킬 수 있다는 것을 결코 알지 못했습니다. 감사.
Basil Bourque 2015 년

2
Down-Voter 님, 투표와 함께 비판을 남겨주세요.
Basil Bourque

"당신이 끔찍한 오래된 java.util.Date 클래스 사용을 고집한다면". 많은 제공 업체가 JDK7 이상으로 Java에서 실행되는 tomcat 서버를 제공하지 않습니다. 그래서 새로운 것을 사용하고 싶지만 일부는 다른 것들 때문에 오래된 문제에 갇혀 있습니다 .....
KimvdLinde

@KimvdLinde 내 답변을 더 신중하게 다시 읽으십시오. 총알을보세요. "Java SE 6 및 Java SE 7"이라는 단어를 찾습니다.
Basil Bourque

14

가장 좋은 방법은 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
JGFMK

9

Java8에서 :

import java.time.Instant;
import java.util.Date;

Date date = Date.from(Instant.parse("2000-01-01T00:00:00.000Z"))

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();

1
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 년에 사용을 제안하는 것은 좋지 않은 조언입니다.
Basil Bourque

이 답변은이 질문의 세부 사항을 다루지 않습니다.
Basil Bourque

1
'API 수준'이란 Android를 의미한다고 가정합니다. 그러나 이것은 Android 관련 질문이 아닙니다. 또한 대부분의 java.time 기능은 ThreeTen-Backport 프로젝트 에서 Java 6 및 7로 백 포트됩니다 . ThreeTenABP 프로젝트 에서 Android에 추가로 적용되었습니다 . 따라서 이러한 끔찍한 레거시 날짜-시간 클래스를 사용할 필요가 없습니다. java.time의 클래스는 근본적으로 더 낫다.
Basil Bourque

이 댓글에 감사드립니다.이 라이브러리는 날짜 차이 및 시간 차이와 같은 기능을 제공합니까?
Syed Danish Haider

1
예. 이 주제에 대한 많은 기존 Q & A에 대해 Stack Overflow를 검색하십시오. ThreeTen-Extra 프로젝트도 참조하십시오 (초기 Android로 백 포팅되지 않음).
Basil Bourque

0

가장 간단한 방법 :

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)읽기가 좀 더 명확합니다.
Ole VV

그리고 답변에 LocalDate 선언이 포함되어 있기 때문에 요청 된 Date 객체 (더 이상 사용되지 않고 가끔 사용됨)뿐만 아니라 ...
Adam Silenko

-1
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 객체 내부에서 구문 분석합니다. 위의 프로그램은 날짜를 지정하여 요일을 얻는 방법을 보여줍니다.
Ankush

-5

나는 당신의 날짜가 PHP에서 왔으며 html (dom) 또는? 모든 날짜와 타임 스탬프를 준비하는 PHP 기능이 있습니다. 이것은 필요한 포메이션을 반환합니다.

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

이 형식은 js에서 새 날짜를 만드는 데 사용할 수 있습니다.

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

내가 말하고자하는 것은, 당신의 삶을 더 편하게 만드는 자신 만의 기능을 감싸는 것입니다. 내 func를 샘플로 사용할 수 있지만 내 cms에 포함되어 있으므로 1 대 1 복사하여 붙여 넣을 수 없습니다. :)

    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();
}

2
PHP로 2 년 이상 된 Java 질문에 대답하는 이유는 무엇 입니까?
Alan Hay
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.