Maison  >  Article  >  Java  >  Comment SpringBoot affiche-t-il dynamiquement l'heure en fonction du fuseau horaire du système de l'utilisateur ?

Comment SpringBoot affiche-t-il dynamiquement l'heure en fonction du fuseau horaire du système de l'utilisateur ?

WBOY
WBOYavant
2023-05-17 08:10:051911parcourir

Affichage dynamique de l'heure en fonction du fuseau horaire du système utilisateur

Lorsque nous utilisons SpringBoot+Mysql pour développer le système, nous définissons toujours le fuseau horaire UTC+8 de manière uniforme. De cette façon, lorsque les utilisateurs accèdent au système dans n'importe quelle région, l'heure affichée. l'heure est l'heure standard nationale, ce qui est une expérience peu conviviale. Ensuite, affichez différentes heures à l'utilisateur en obtenant le fuseau horaire du système utilisateur actuel.

1. Obtention du fuseau horaire de l'utilisateur

Nous pouvons obtenir le fuseau horaire du système via JavaScript, puis le définir uniformément dans l'en-tête de la requête.

Intl.DateTimeFormat().resolvedOptions().timeZone; // Asia/Shanghai

2. Le code principal

LocalDateTime est utilisé ici uniformément pour gérer plus facilement les problèmes de conversion de fuseau horaire en identifiant le fuseau horaire auquel appartient l'objet LocalDateTime actuel, puis en le convertissant en heure de fuseau horaire cible.

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

3. SpringBoot traite uniformément le fuseau horaire lors du retour de json

Lorsque le programme lit la base de données et la convertit en un objet LocalDateTime, et le traite via la logique métier, l'objet appartient toujours au fuseau horaire UTC+8, et le ZoneId=Asia/Shanghai correspondant, lorsqu'il doit être renvoyé au front-end, vous pouvez utiliser un sérialiseur Jackson personnalisé pour convertir le LocalDateTime dans le fuseau horaire cible de l'utilisateur avant de le convertir en 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())));
		};
	}
}

L'exemple de code ci-dessus définit le fuseau horaire de l'utilisateur ZoneId=Africa/Sao_Tome et personnalise le désérialiseur LocalDateTime. Lors de l'utilisation de l'annotation ResquestBody, la valeur de l'attribut LocalDateTime dans l'objet sera également convertie en fuseau horaire UTC+8, pas besoin. Les traitements supplémentaires peuvent être enregistrés directement dans la base de données.

4. SpringBoot reçoit les paramètres temporels et traite les fuseaux horaires de manière unifiée

En plus de recevoir des paramètres via l'annotation ResquestBody comme mentionné ci-dessus, il est également possible de recevoir des objets LocalDateTime via les paramètres Get ou Post. Vous devez personnaliser un convertisseur pour gérer la conversion de chaîne en LocalDateTime et en même temps convertir les objets soumis par l'utilisateur qui appartiennent au fuseau horaire de l'utilisateur en objets de fuseau horaire UTC+8.

@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"));
			}		});
	}}

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer