이 GMT 타임 스탬프를 GMT + 13으로 변환하고 싶습니다.
2011-10-06 03:35:05
이 아주 기본적인 작업을 수행하기 위해 DateFormat, TimeZone, Date, GregorianCalendar 등의 약 100 가지 다른 조합을 시도했습니다.
이 코드는 현재 시간에 대해 원하는 작업을 수행합니다.
Calendar calendar = new GregorianCalendar(TimeZone.getTimeZone("GMT"));
DateFormat formatter = new SimpleDateFormat("dd MMM yyyy HH:mm:ss z");
formatter.setTimeZone(TimeZone.getTimeZone("GMT+13"));
String newZealandTime = formatter.format(calendar.getTime());
하지만 내가 원하는 것은 현재 시간을 사용하는 것보다 시간을 설정하는 것입니다.
다음과 같이 시간을 설정하려고 할 때마다 발견했습니다.
calendar.setTime(new Date(1317816735000L));
로컬 시스템의 TimeZone이 사용됩니다. 왜 그런 겁니까? “new Date ()”가 UTC + 0 시간을 반환 할 때 시간을 밀리 초로 설정하면 더 이상 시간이 UTC로 간주되지 않는 이유는 무엇입니까?
해도 될까요:
- 개체에 시간 설정 (Calendar / Date / TimeStamp)
- (가능) 초기 타임 스탬프의 TimeZone 설정 (calendar.setTimeZone (…))
- 새 TimeZone (formatter.setTimeZone (…)))으로 타임 스탬프 서식 지정
- 새로운 시간대 시간이있는 문자열을 반환합니다. (formatter.format (calendar.getTime ()))
도움을 주셔서 미리 감사드립니다 : D
답변
저에게 가장 간단한 방법은 다음과 같습니다.
Calendar calendar = Calendar.getInstance();
calendar.setTime(new Date());
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
//Here you say to java the initial timezone. This is the secret
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
//Will print in UTC
System.out.println(sdf.format(calendar.getTime()));
//Here you set to your timezone
sdf.setTimeZone(TimeZone.getDefault());
//Will print on your default Timezone
System.out.println(sdf.format(calendar.getTime()));
답변
컴퓨터 시간이 어떻게 작동하는지 이해하는 것은 매우 중요합니다. 즉, 실시간처럼 컴퓨터 시간을 처리 할 수 있도록 API가 생성되면 실시간으로 처리 할 수있는 방식으로 작동해야한다는 데 동의합니다. 대부분의 경우 이것이 사실이지만주의가 필요한 몇 가지 주요 감독이 있습니다.
어쨌든 나는 탈선 !! UTC 오프셋이있는 경우 (GMT 오프셋보다 UTC에서 작업하는 것이 더 좋음) 시간을 밀리 초 단위로 계산하여 타임 스탬프에 추가 할 수 있습니다. SQL 타임 스탬프는 에포크로부터의 경과가 계산되는 방식이 항상 동일하지는 않기 때문에 Java 타임 스탬프와 다를 수 있습니다. 데이터베이스 기술 및 운영 체제에 따라 다릅니다.
System.currentTimeMillis ()를 타임 스탬프로 사용하는 것이 좋습니다. SQL 타임 스탬프를 Java Date 객체로 변환하는 것에 대해 걱정하지 않고 Java에서 더 일관되게 처리 할 수 있기 때문입니다.
오프셋을 계산하려면 다음과 같이 시도해 볼 수 있습니다.
Long gmtTime =1317951113613L; // 2.32pm NZDT
Long timezoneAlteredTime = 0L;
if (offset != 0L) {
int multiplier = (offset*60)*(60*1000);
timezoneAlteredTime = gmtTime + multiplier;
} else {
timezoneAlteredTime = gmtTime;
}
Calendar calendar = new GregorianCalendar();
calendar.setTimeInMillis(timezoneAlteredTime);
DateFormat formatter = new SimpleDateFormat("dd MMM yyyy HH:mm:ss z");
formatter.setCalendar(calendar);
formatter.setTimeZone(TimeZone.getTimeZone(timeZone));
String newZealandTime = formatter.format(calendar.getTime());
도움이 되었기를 바랍니다.
답변
항상 그렇듯이 Java의 날짜 및 시간에 대한 이 기사 를 읽고 이해할 수 있도록하는 것이 좋습니다 .
기본 아이디어는 ‘내부에서’모든 것이 에포크 이후 UTC 밀리 초 단위로 수행된다는 것입니다. 즉, 사용자에 대한 문자열 형식을 제외하고 시간대를 전혀 사용하지 않고 작업하는 것이 가장 쉽습니다.
따라서 귀하가 제안한 대부분의 단계를 건너 뛸 것입니다.
- 개체 (날짜, 달력 등)에 시간을 설정합니다.
- 포맷터 개체에 표준 시간대를 설정합니다.
- 포맷터에서 문자열을 반환합니다.
또는 Joda time을 사용할 수 있습니다 . 훨씬 더 직관적 인 datetime API라고 들었습니다.
답변
tl; dr
Instant.ofEpochMilli( 1_317_816_735_000L )
.atZone( ZoneId.of( "Pacific/Auckland" ) )
.format( DateTimeFormatter.ofLocalizedDateTime( FormatStyle.MEDIUM ).withLocale( new Locale( "en" , "NZ" ) ) )
…또한…
LocalDateTime.parse( "2011-10-06 03:35:05".replace( " " , "T" ) )
.atZone( ZoneId.of( "Pacific/Auckland" ) )
java.time
질문과 대부분의 답변은 초기 Java 버전의 오래된 레거시 날짜-시간 클래스를 사용합니다. 이러한 오래된 수업은 번거롭고 혼란스러운 것으로 입증되었습니다. 그들을 피하십시오. 대신 java.time 클래스를 사용하십시오.
ISO 8601
입력 문자열은 거의 표준 ISO 8601 형식입니다. 중간의 SPACE를 T
.
String input = "2011-10-06 03:35:05".replace( " " , "T" );
LocalDateTime
LocalDateTime
입력에 UTC 또는 시간대에 대한 정보가 없기 때문에 이제 a로 구문 분석 하십시오. A LocalDateTime
에는 오프셋이나 시간대에 대한 개념이 없으므로 타임 라인의 실제 순간을 않습니다 .
LocalDateTime ldt = LocalDateTime.parse( input );
ZoneOffset
비즈니스 컨텍스트에서이 문자열의 의도는 UTC보다 13 시간 앞선 순간을 나타내는 것임을 알고있는 것 같습니다. 그래서 우리는ZoneOffset
.
ZoneOffset offset = ZoneOffset.ofHours( 13 ); // 13 hours ahead of UTC, in the far east of the globe.
OffsetDateTime
그것을 얻기 위하여 그것을 적용하십시오 OffsetDateTime
개체 . 이것은 타임 라인의 실제 순간이됩니다.
OffsetDateTime odt = ldt.atOffset( offset);
ZoneId
하지만 당신은 뉴질랜드를 언급합니다. 따라서 특정 시간대를 염두에 두었습니다. 시간대는 UTC로부터의 오프셋입니다. 플러스 같은 일광 절약 시간 (DST)과 같은 이상을 처리하기위한 규칙들의 집합. 따라서 우리는 단순한 오프셋 ZoneId
이 ZonedDateTime
아닌 a 를 지정할 수 있습니다 .
적절한 시간대 이름을 지정하십시오 . EST
또는 IST
과 같은 3-4 자의 약어를 사용하지 마십시오. 표준 시간대가 아니고 고유하지도 않습니다 (!). 예를 들면Pacific/Auckland
.
ZoneId z = ZoneId.of( "Pacific/Auckland" );
ZonedDateTime
적용 ZoneId
.
ZonedDateTime zdt = ldt.atZone( z );
타임 라인에서 같은 순간에 다른 영역으로 쉽게 조정할 수 있습니다.
ZoneId zParis = ZoneId.of( "Europe/Paris" );
ZonedDateTime zdtParis = zdt.withZoneSameInstant( zParis ); // Same moment in time, but seen through lens of Paris wall-clock time.
시대부터 계산
1970 UTC가 시작된 후의 밀리 초와 같은 epoch의 카운트로 날짜-시간 값을 처리하지 않는 것이 좋습니다. 하지만 필요한 경우Instant
이러한 번호에서 .
Instant instant = Instant.ofEpochMilli( 1_317_816_735_000L );
그런 다음 원하는 경우 위에 표시된대로 시간대를 지정하여 UTC에서 벗어나십시오.
ZoneId z = ZoneId.of( "Pacific/Auckland" );
ZonedDateTime zdt = instant.atZone( z );
귀하의 가치 1_317_816_735_000L
는 다음과 같습니다.
2011-10-05T12:12:15Z
(2011 년 10 월 5 일 수요일 12:12:15 GMT)2011-10-06T01:12:15+13:00[Pacific/Auckland]
(2011 년 10 월 6 일 목요일 뉴질랜드 오클랜드에서 01:12:15).
문자열 생성
표준 ISO 8601 형식으로 문자열을 생성하려면 toString
. ZonedDateTime
시간대 이름을 대괄호로 묶어 표준 형식 을 현명하게 확장합니다.
String output = zdt.toString();
다른 형식의 경우 Stack Overflow에서 DateTimeFormatter
클래스를 검색하십시오 . 이미 여러 번 다루었습니다.
a FormatStyle
및 Locale
.
Locale l = new Locale( "en" , "NZ" );
DateTimeFormatter f = DateTimeFormatter.ofLocalizedDateTime( FormatStyle.MEDIUM ).withLocale( l );
String output = zdt.format( f );
시간대는 로케일과 관련 이 없습니다 . 당신은 할 수 있습니다 Europe/Paris
날짜와 시간이 일본어 및 문화적 규범, 또는 표시 Asia/Kolkata
포르투갈어, 브라질 문화적 규범에 표시되는 날짜 – 시간.
java.time 정보
java.time의 프레임 워크는 나중에 자바 8에 내장되어 있습니다. 이러한 클래스는 같은 귀찮은 된 날짜 – 시간의 수업을 대신하는 java.util.Date
, .Calendar
, java.text.SimpleDateFormat
.
Joda 타임 지금 프로젝트, 유지 관리 모드 , java.time로 마이그레이션을 조언한다.
자세한 내용은 Oracle Tutorial을 참조하십시오 . 그리고 많은 예제와 설명을 위해 Stack Overflow를 검색하십시오.
많은 java.time 기능은 자바 6 & 7 백 포팅 ThreeTen – 백 포트 추가에 적응 안드로이드 에 ThreeTenABP (참조 … 사용 방법 ).
ThreeTen – 추가 프로젝트 추가 클래스와 java.time를 확장합니다. 이 프로젝트는 java.time에 향후 추가 될 수있는 가능성을 입증하는 근거입니다. 여기 Interval
에서 YearWeek
,, 등과 같은 유용한 클래스를 찾을 수 있습니다 YearQuarter
.
답변
솔루션은 실제로 매우 간단합니다 (순수하고 단순한 Java).
System.out.println(" NZ Local Time: 2011-10-06 03:35:05");
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
LocalDateTime localNZ = LocalDateTime.parse("2011-10-06 03:35:05",formatter);
ZonedDateTime zonedNZ = ZonedDateTime.of(localNZ,ZoneId.of("+13:00"));
LocalDateTime localUTC = zonedNZ.withZoneSameInstant(ZoneId.of("UTC")).toLocalDateTime();
System.out.println("UTC Local Time: "+localUTC.format(formatter));
출력은 :
NZ Local Time: 2011-10-06 03:35:05
UTC Local Time: 2011-10-05 14:35:05
답변
살펴 보았고 Java에 GMT + 13 인 시간대가 있다고 생각하지 않습니다. 따라서 다음을 사용해야한다고 생각합니다.
Calendar calendar = Calendar.getInstance();
//OR Calendar.getInstance(TimeZone.getTimeZone("GMT"));
calendar.set(Calendar.HOUR_OF_DAY, calendar.get(Calendar.HOUR_OF_DAY)+13);
Date d = calendar.getTime();
(그런 다음 “GMT”를 해당 시간대로 변경하고 코드의 두 번째 줄을 제거하십시오)
또는
SimpleDateFormat df = new SimpleDateFormat();
df.setTimeZone(TimeZone.getTimeZone("GMT+13"));
System.out.println(df.format(c.getTime()));
특정 시간 / 날짜를 설정하려면 다음을 사용할 수도 있습니다.
calendar.set(Calendar.DATE, 15);
calendar.set(Calendar.MONTH, 3);
calendar.set(Calendar.YEAR, 2011);
calendar.set(Calendar.HOUR_OF_DAY, 13);
calendar.set(Calendar.MINUTE, 45);
calendar.set(Calendar.SECOND, 00);
답변
오프셋 값을 사용하여 처리 할 수 있습니다.
public static long convertDateTimeZone(long lngDate, String fromTimeZone,
String toTimeZone){
TimeZone toTZ = TimeZone.getTimeZone(toTimeZone);
Calendar toCal = Calendar.getInstance(toTZ);
TimeZone fromTZ = TimeZone.getTimeZone(fromTimeZone);
Calendar fromCal = Calendar.getInstance(fromTZ);
fromCal.setTimeInMillis(lngDate);
toCal.setTimeInMillis(fromCal.getTimeInMillis()
+ toTZ.getOffset(fromCal.getTimeInMillis())
- TimeZone.getDefault().getOffset(fromCal.getTimeInMillis()));
return toCal.getTimeInMillis();
}
테스트 코드 스 니펫 :
System.out.println(new Date().getTime())
System.out.println(convertDateTimeZone(new Date().getTime(), TimeZone
.getDefault().getID(), "EST"));
출력 : 1387353270742 1387335270742