Home > Java > javaTutorial > How does SpringBoot dynamically display time based on the user's system time zone?

How does SpringBoot dynamically display time based on the user's system time zone?

WBOY
Release: 2023-05-17 08:10:05
forward
1949 people have browsed it

Dynamic display of time based on user system time zone

When we use SpringBoot Mysql to develop the system, we always set the UTC 8 time zone uniformly, so that when users access the system in any region, the time displayed is the domestic standard time. The experience is not user-friendly. Let’s get the time zone of the current user’s system to show different times to the user.

1. Obtaining the user time zone

We can obtain the time zone of the system through JavaScript, and then set it uniformly in the request header.

Intl.DateTimeFormat().resolvedOptions().timeZone; // Asia/Shanghai
Copy after login

2. Core code

LocalDateTime is used uniformly here to more conveniently handle time zone conversion issues by identifying the time zone to which the current LocalDateTime object belongs and then converting it to the target time zone time.

public LocalDateTime convertLocalDateTime(LocalDateTime localDateTime, ZoneId originZoneId,
			ZoneId targetZoneId)
{
	return localDateTime.atZone(originZoneId).withZoneSameInstant(targetZoneId).toLocalDateTime();
}
Copy after login

3. SpringBoot uniformly processes the time zone when returning json

When the program reads from the database and converts it into a LocalDateTime object, and processes it with business logic, the object still belongs to UTC 8. Time zone, the corresponding ZoneId=Asia/Shanghai, when it needs to be returned to the front end, you can use a custom jackson serializer to convert the LocalDateTime to the user's target time zone before converting it to json.

@Configuration
public class JacksonConfiguration
{
	@Autowired
	private JacksonProperties jacksonProperties;	/**
	 * 时区转换
	 * 
	 * @param localDateTime
	 * @param originZoneId
	 * @param targetZoneId
	 * @return
	 */
	public static LocalDateTime convertLocalDateTime(LocalDateTime localDateTime, ZoneId originZoneId,
			ZoneId targetZoneId)
	{
		return localDateTime.atZone(originZoneId).withZoneSameInstant(targetZoneId).toLocalDateTime();
	}	/**
	 * LocalDateTime序列化
	 */
	public static class CustomLocalDateTimeSerializer extends JsonSerializer<LocalDateTime>
	{
		private DateTimeFormatter formatter;		public CustomLocalDateTimeSerializer(DateTimeFormatter formatter)
		{
			super();
			this.formatter = formatter;
		}		@Override
		public void serialize(LocalDateTime value, JsonGenerator generator, SerializerProvider provider)
				throws IOException
		{
			generator.writeString(convertLocalDateTime(value, ZoneId.of("Asia/Shanghai"), ZoneId.of("Africa/Sao_Tome"))
					.format(formatter));
		}	}	/**
	 * LocalDateTime反序列化
	 * 
	 */
	public static class CustomLocalDateTimeDeserializer extends JsonDeserializer<LocalDateTime>
	{
		private DateTimeFormatter formatter;		public CustomLocalDateTimeDeserializer(DateTimeFormatter formatter)
		{
			super();
			this.formatter = formatter;
		}		@Override
		public LocalDateTime deserialize(JsonParser parser, DeserializationContext context)
				throws IOException, JacksonException
		{
			return convertLocalDateTime(LocalDateTime.parse(parser.getText(), formatter), ZoneId.of("Africa/Sao_Tome"),
					ZoneId.of("Asia/Shanghai"));
		}	}	@Bean
	public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer()
	{
		return builder ->
		{
			builder.serializerByType(LocalDateTime.class,
					new CustomLocalDateTimeSerializer(DateTimeFormatter.ofPattern(jacksonProperties.getDateFormat())));
			builder.deserializerByType(LocalDateTime.class,
					new CustomLocalDateTimeDeserializer(DateTimeFormatter.ofPattern(jacksonProperties.getDateFormat())));
		};
	}
}
Copy after login

The above example code sets the user time zone ZoneId=Africa/Sao_Tome, and customizes the LocalDateTime deserializer. When using the ResquestBody annotation, the LocalDateTime attribute value in the object will also be converted to UTC 8 time zone , no additional processing is required and can be saved directly to the database.

4. SpringBoot receives time parameters and processes time zones uniformly

In addition to receiving parameters through the ResquestBody annotation as mentioned above, it is also possible to receive LocalDateTime objects through Get or Post parameters. At this time we need to Customize a Converter to handle the conversion of String to LocalDateTime, and at the same time convert the objects submitted by the user that belong to the user's time zone into UTC 8 time zone objects.

@Configuration
public class WebMvcConfiguration implements WebMvcConfigurer
{
	@Autowired
	private WebMvcProperties webMvcProperties;	@Override
	public void addFormatters(FormatterRegistry registry)
	{
		registry.addConverter(new Converter<String, LocalDateTime>()
		{			private LocalDateTime convertLocalDateTime(LocalDateTime localDateTime, ZoneId originZoneId,
					ZoneId targetZoneId)
			{
				return localDateTime.atZone(originZoneId).withZoneSameInstant(targetZoneId).toLocalDateTime();
			}			@Override
			public LocalDateTime convert(String source)
			{
				return convertLocalDateTime(
						LocalDateTime.parse(source,
								DateTimeFormatter.ofPattern(webMvcProperties.getFormat().getDateTime())),
						ZoneId.of("Africa/Sao_Tome"), ZoneId.of("Asia/Shanghai"));
			}		});
	}}
Copy after login

The above is the detailed content of How does SpringBoot dynamically display time based on the user's system time zone?. For more information, please follow other related articles on the PHP Chinese website!

Related labels:
source:yisu.com
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template