programing

gson을 사용한 Java 날짜 UTC

lastmoon 2023. 2. 26. 10:24
반응형

gson을 사용한 Java 날짜 UTC

java에서 날짜 시간을 UTC로 변환하도록 gson을 구할 수 없는 것 같습니다.여기 내 코드가 있다...

Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'").create();
//This is the format I want, which according to the ISO8601 standard - Z specifies UTC - 'Zulu' time

Date now=new Date();          
System.out.println(now);       
System.out.println(now.getTimezoneOffset());
System.out.println(gson.toJson(now));

출력은 다음과 같습니다.

Thu Sep 25 18:21:42 BST 2014           // Time now - in British Summer Time 
-60                                    // As expected : offset is 1hour from UTC    
"2014-09-25T18:21:42.026Z"             // Uhhhh this is not UTC ??? Its still BST !!

원하는 gson 결과와 기대했던 것

"2014-09-25T17:21:42.026Z"

Json에게 통화하기 1시간 전에 뺄 수 있는데 해킹인 것 같아요.항상 UTC로 변환하도록 gson을 설정하려면 어떻게 해야 합니까?

좀 더 조사한 결과, 이것은 이미 알려진 문제인 것으로 보입니다.gson 디폴트시리얼라이저는 항상 디폴트로 로컬타임존으로 설정되어 타임존을 지정할 수 없습니다.다음 링크를 참조하십시오.

https://code.google.com/p/google-gson/issues/detail?id=281

해결 방법은 링크에 나와 있는 커스텀 gson 타입 어댑터를 작성하는 것입니다.

// this class can't be static
public class GsonUTCDateAdapter implements JsonSerializer<Date>,JsonDeserializer<Date> {

    private final DateFormat dateFormat;

    public GsonUTCDateAdapter() {
      dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.US);      //This is the format I need
      dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));                               //This is the key line which converts the date to UTC which cannot be accessed with the default serializer
    }

    @Override public synchronized JsonElement serialize(Date date,Type type,JsonSerializationContext jsonSerializationContext) {
        return new JsonPrimitive(dateFormat.format(date));
    }

    @Override public synchronized Date deserialize(JsonElement jsonElement,Type type,JsonDeserializationContext jsonDeserializationContext) {
      try {
        return dateFormat.parse(jsonElement.getAsString());
      } catch (ParseException e) {
        throw new JsonParseException(e);
      }
    }
}

다음에, 다음과 같이 등록합니다.

  Gson gson = new GsonBuilder().registerTypeAdapter(Date.class, new GsonUTCDateAdapter()).create();
  Date now=new Date();
  System.out.println(gson.toJson(now));

이것으로 날짜(UTC)가 올바르게 출력됩니다.

"2014-09-25T17:21:42.026Z"

링크 작성자에게 감사합니다.

날짜 형식의 Z는 단일 따옴표로 표시되므로 실제 시간대로 대체하려면 따옴표를 삭제해야 합니다.

또한 UTC로 날짜를 변환하려면 먼저 변환하십시오.

이 문제의 해결 방법은 커스텀 날짜 어댑터(P)를 작성하는 것이었습니다.Import 할 수 있도록 주의해 주세요.java.util.Date것은 아니다.java.sql.Date!)

public class ColonCompatibileDateTypeAdapter implements JsonSerializer<Date>, JsonDeserializer< Date> {
private final DateFormat dateFormat;

public ColonCompatibileDateTypeAdapter() {
  dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ") {
        @Override
        public StringBuffer format(Date date, StringBuffer toAppendTo, FieldPosition pos) {
            StringBuffer rfcFormat = super.format(date, toAppendTo, pos);
            return rfcFormat.insert(rfcFormat.length() - 2, ":");
        }

        @Override
        public Date parse(String text, ParsePosition pos) {
            if (text.length() > 3) {
                text = text.substring(0, text.length() - 3) + text.substring(text.length() - 2);
            }
            return super.parse(text, pos);
        }
    };


}

@Override public synchronized JsonElement serialize(Date date, Type type,
    JsonSerializationContext jsonSerializationContext) {
  return new JsonPrimitive(dateFormat.format(date));
}

@Override public synchronized Date deserialize(JsonElement jsonElement, Type type,
    JsonDeserializationContext jsonDeserializationContext) {
  try {
      return dateFormat.parse(jsonElement.getAsString());
  } catch (ParseException e) {
    throw new JsonParseException(e);
  }
}}

그런 다음 GSON 개체를 만들 때 사용합니다.

Gson gson = new GsonBuilder().registerTypeAdapter(Date.class, new ColonCompatibileDateTypeAdapter()).create();

는 표시된 솔루션을 수정하고 파라메타화했다.DateFormat:

import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonParseException;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;

import java.lang.reflect.Type;
import java.text.DateFormat;
import java.text.ParseException;
import java.util.Date;

public class GsonDateFormatAdapter implements JsonSerializer<Date>, JsonDeserializer<Date> {

    private final DateFormat dateFormat;

    public GsonDateFormatAdapter(DateFormat dateFormat) {
        this.dateFormat = dateFormat;
    }

    @Override
    public synchronized JsonElement serialize(Date date, Type type, JsonSerializationContext jsonSerializationContext) {
        return new JsonPrimitive(dateFormat.format(date));
    }

    @Override
    public synchronized Date deserialize(JsonElement jsonElement, Type type,JsonDeserializationContext jsonDeserializationContext) {
        try {
            return dateFormat.parse(jsonElement.getAsString());
        } catch (ParseException e) {
            throw new JsonParseException(e);
        }
    }
}

Kotlin에서는 어떤 대답도 통하지 않았기 때문에, 저는 스스로 실장했습니다.

val SERVER_DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss" // Adjust as per your use case

val gson = GsonBuilder()
    .setDateFormat(SERVER_DATE_FORMAT)
    .registerTypeAdapter(Date::class.java, object : JsonSerializer<Date> {
        private val utcDateFormat = SimpleDateFormat(
            SERVER_DATE_FORMAT,
            Locale.ENGLISH
        ).apply {
            timeZone = TimeZone.getTimeZone("UTC")
        }

        // Avoid using local date formatter (with timezone) to send UTC date
        override fun serialize(src: Date?, typeOfSrc: Type?, context: JsonSerializationContext?): JsonElement {
            return JsonPrimitive(src?.let { utcDateFormat.format(it) })
        }
    })
    .create()
val gsonConverterFactory = GsonConverterFactory.create(gson)

val retrofit = Retrofit.Builder()
    .baseUrl("Your URL")
    .addConverterFactory(gsonConverterFactory)
    .build()

이게 다른 사람에게 유용했으면 좋겠어!

언급URL : https://stackoverflow.com/questions/26044881/java-date-to-utc-using-gson

반응형