글로벌 서비스 개발시 Timezone 에 맞춰 날짜 표기하기.
개발환경 : Spring 4.0
JDK : 1.7
날짜 표기가 중요한 글로벌 서비스를 제작시 전세계 타임존에 맞는 시간으로 포맷을 변경해줘야 한다.
서버시간인 서울 타임존을 기준으로 각 타임존에 맞는 시간으로 포맷 변경해주기 위한 제반 개발 절차를 정의한다.
- pom.xml
JDK 기본날짜 클래스에서 제공하는 java.util.Date, java.util.Calendar 클래스는 일관성이 없고 상수의 혼란, 일관성이 없으므로
가급적이면 joda-time을 사용하길 권장한다.
joda-time 2.9.9 추가
- 테스트용 테이블 생성
데이터 타입이 VARCHAR인 expired 필드에 밀리세컨드값을 저장하게 됩니다.
CREATE TABLE sl_tz_test
(
idx
int(11) NOT NULL,
expired
varchar(200) DEFAULT NULL,
PRIMARY KEY (idx
)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
- DTO 생성
저장된 밀리세컨드값을 이용하여
서버시간인 서울 타임존을 기준으로 각 타임존에 맞는 시간으로 포맷 변경하여 출력한다.
import org.joda.time.*;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
import java.util.*;
public class TestTimstampVO {
private int idx;
private String expired;
private String expiredLocalTime;
public int getIdx() {
return idx;
}
public void setIdx(int idx){
this.idx=idx;
}
public String getExpired() {
return expired;
}
public void setExpired(String expired){
DateTime expDT = new DateTime(Long.parseLong(expired));
DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyyMMddHHmmss");
formatter.withZone(DateTimeZone.forID("Asia/Seoul"));
String tzExp=getTimeWithTimezone(expDT.toString(formatter),
"yyyyMMddHHmmss",
getMinuteCurrentTzOffset("Europe/Berlin"));
this.expiredLocalTime = tzExp;
this.expired=expired;
}
public String getExpiredLocalTime(){
return expiredLocalTime;
}
public void setExpiredLocalTime(String expiredLocalTime){
this.expiredLocalTime = expiredLocalTime;
}
/**
* 서버시간인 서울 타임존을 기준으로 각 타임존에 맞는 시간으로 포맷 변경하여 출력함.
* @param time 변경 대상 시간
* @param format 시간 포맷
* @param offset 변경할 타임존 offset (분) - (TIMEZONE = +540)
* @return
*/
public static String getTimeWithTimezone(String time, String format, String offset)
{
String result = "";
int timezoneOffset = Integer.parseInt(offset.replace("+", ""));
try {
if( !offset.equals("+540") ) { // 서울 시간이 아닌경우에만 로직 수행
DateTimeZone seoulTZ = DateTimeZone.forID("Asia/Seoul");
DateTimeZone outputTz = DateTimeZone.forOffsetMillis(timezoneOffset * 60 * 1000); // 출력하고자 하는 Timezone 으로 변환
DateTimeFormatter df = DateTimeFormat.forPattern(format + " Z");
DateTime temp = df.withOffsetParsed().parseDateTime(time + " +0900"); // 서버시간인 서울시간 기준으로 입력
Date date = temp.toDate();
DateTime dateTime = new DateTime(date);
DateTimeFormatter df2 = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss");
DateTimeFormatter df3 = df2.withZone(seoulTZ);
DateTimeFormatter rdf = DateTimeFormat.forPattern(format);
DateTimeFormatter wdd = rdf.withZone(outputTz);
result = dateTime.toString(wdd);
}else{
result = time;
}
} catch (Exception e) {
result = time;
}
System.out.println("타임존 offset : "+offset);
System.out.println("입력된 시간 : "+time);
System.out.println("변환 시간 :"+ result);
return result;
}
/**
* 타임존 아이디의 밀리세컨드 offset을 구하고 이를 (분)으로 변경
* @param zoneId
* @return
*/
public static String getMinuteCurrentTzOffset(String zoneId) {
int offsetInMillis = DateTimeZone.forID(zoneId).getOffset(new DateTime().getMillis());
int minute=(Math.abs(offsetInMillis / 3600000) * 60) + ((offsetInMillis / 60000) % 60);
String offsetMinute = (offsetInMillis >= 0 ? "+" : "-") + minute;
return offsetMinute;
}
/**
* 타임존 아이디에 해당하는 offset을 구함 (시간단위) .
* @param zoneId
* @return
*/
public static String getCurrentTzOffset(String zoneId) {
int offsetInMillis = DateTimeZone.forID(zoneId).getOffset(new DateTime().getMillis());
String offset = String.format("%02d:%02d", Math.abs(offsetInMillis / 3600000),
Math.abs((offsetInMillis / 60000) % 60));
offset = (offsetInMillis >= 0 ? "+" : "-") + offset;
return offset;
}
}
- 프론트 jquery
javascript의 Date 오브젝트에 'YYYYMMDDHHMMSS' 프로토타입 추가하고
아래처럼 호출하여 Date Format을 맞춰준 후 서버측으로 보낸다.
var exp=$("#expired").val();
console.log(parseInt(new Date(exp).YYYYMMDDHHMMSS()));
Object.defineProperty(Date.prototype, 'YYYYMMDDHHMMSS', {
value: function() {
function pad2(n) { // always returns a string
return (n < 10 ? '0' : '') + n;
}
return this.getFullYear() +
pad2(this.getMonth() + 1) +
pad2(this.getDate()) +
pad2(this.getHours()) +
pad2(this.getMinutes()) +
pad2(this.getSeconds());
}
});
- 서버사이드
수신한 YYYYMMDDHHMMSS 값을 DateTimeZone.UTC 밀리세컨드로 변환 후
위에 기술한 테이블의 VARCHAR 타입의 필드에 String으로 입력한다.
DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyyMMddHHmmss");
DateTime dt = new DateTime(formatter.parseDateTime(String.valueOf(tzvo.getExpired())), DateTimeZone.UTC);
System.out.println("millis: " + dt.getMillis());
Congratulations @rumbus! You received a personal award!
You can view your badges on your Steem Board and compare to others on the Steem Ranking
Do not miss the last post from @steemitboard:
Vote for @Steemitboard as a witness to get one more award and increased upvotes!
Congratulations @rumbus! You received a personal award!
Click here to view your Board