ตัวอย่างการเขียน Spring-boot Reactive Default Time Zone
- มีความเข้าใจเรื่อง Time Zone
- ถ้าไม่เข้าใจสามารถเรียนรู้ได้จาก สรุปสั้น ๆ เรื่องเขตเวลา (Time Zone) และไขข้อสงสัยว่าทำไมเวลาประเทศไทยถึงเป็น UTC+7
- ถ้าใครใช้ Server เป็น Ubuntu สามารถดูตัวอย่างการ Set Time Zone ได้จาก ตั้งค่า Time Zone สำหรับ Ubuntu 20.04 LTS
pom.xml
...
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.1</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<id>build-info</id>
<goals>
<goal>build-info</goal>
</goals>
<configuration>
<additionalProperties>
<java.version>${java.version}</java.version>
</additionalProperties>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
...
@SpringBootApplication
public class AppStarter {
public static void main(String[] args) {
SpringApplication.run(AppStarter.class, args);
}
}
สร้าง Java Class Config ขึ้นมา แล้วกำหนด Time Zone ตามที่ต้องการ
@Slf4j
@Configuration
public class TimeZoneConfig {
@PostConstruct
public void setDefaultTimeZone(){
TimeZone.setDefault(TimeZone.getTimeZone("Asia/Bangkok"));
log.info("set Default Time Zone => {}", TimeZone.getDefault().getID());
}
}
คำอธิบาย
- โดยปกติ
TimeZone.getDefault()
จะทำการอ่านค่า Time Zone มาจากเครื่อง- ถ้าเครื่องเรา Default Time Zone เป็น
UTC
แล้วTimeZone.getDefault()
ก็จะได้UTC
เช่นเดียวกัน - ถ้าเครื่องเรา Default Time Zone เป็น
Asia/Bangkok
แล้วTimeZone.getDefault()
ก็จะได้Asia/Bangkok
เช่นเดียวกัน - เพราะฉะนั้น ต้องระวังเวลาเอา App ไป Deploy ให้เช็คเสมอว่าเครื่องนั้น Default Time Zone เป็นอะไร
- ถ้าเครื่องเรา Default Time Zone เป็น
- เพื่อป้องกันข้อผิดพลาดอีกชั้น เราสามารถ Set Time Zone App เองได้โดยการใช้
TimeZone.setDefault(...)
- กำหนดให้ Java (8+ DateTime) ใช้ Default Time Zone เป็น
Asia/Bangkok
หรือUTC+7
@RestController
@RequestMapping("/time-zones")
public class TimeZoneController {
@GetMapping
public Flux<TimeZone> getAvailableTimeZones(){
return Flux.fromIterable(Arrays.asList(TimeZone.getAvailableIDs()))
.map(TimeZone::getTimeZone);
}
@GetMapping("/default")
public Mono<TimeZone> getDefault() {
return Mono.just(TimeZone.getDefault());
}
@GetMapping("/current-datetime")
public Mono<DTO> currentDateTime(){
return Mono.just(
DTO.builder()
.instant(Instant.now())
.localDate(LocalDate.now())
.localDateTime(LocalDateTime.now())
.offsetDateTime(OffsetDateTime.now())
.offsetTime(OffsetTime.now())
.zonedDateTime(ZonedDateTime.now())
.build()
);
}
@Data
@Builder
public static class DTO {
private Instant instant;
private LocalDate localDate;
private LocalDateTime localDateTime;
private OffsetDateTime offsetDateTime;
private OffsetTime offsetTime;
private ZonedDateTime zonedDateTime;
}
}
cd ไปที่ root ของ project จากนั้น
$ mvn clean package
$ mvn spring-boot:run
เปิด browser แล้วเข้า http://localhost:8080/times-zones
Default Time Zone
Time Zone = UTC
{
"instant": "2020-10-29T07:06:21.179857Z",
"localDate": "2020-10-29",
"localDateTime": "2020-10-29T07:06:21.179935",
"offsetDateTime": "2020-10-29T07:06:21.179983Z",
"offsetTime": "07:06:21.180089Z",
"zonedDateTime": "2020-10-29T07:06:21.180115Z"
}
Time Zone = Asia/Bangkok
(UTC+7)
{
"instant": "2020-10-29T07:03:07.954985Z",
"localDate": "2020-10-29",
"localDateTime": "2020-10-29T14:03:07.957173",
"offsetDateTime": "2020-10-29T14:03:07.957225+07:00",
"offsetTime": "14:03:07.957357+07:00",
"zonedDateTime": "2020-10-29T14:03:07.957389+07:00"
}
Time Zone = Asia/Singapore
(UTC+8)
{
"instant": "2020-10-29T07:09:33.056406Z",
"localDate": "2020-10-29",
"localDateTime": "2020-10-29T15:09:33.058546",
"offsetDateTime": "2020-10-29T15:09:33.058584+08:00",
"offsetTime": "15:09:33.058701+08:00",
"zonedDateTime": "2020-10-29T15:09:33.058729+08:00"
}