001/* 002 * Copyright 2002-2017 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * https://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.format.datetime.standard; 018 019import java.time.ZoneId; 020import java.time.chrono.Chronology; 021import java.time.format.DateTimeFormatter; 022import java.util.TimeZone; 023 024import org.springframework.context.i18n.LocaleContext; 025import org.springframework.context.i18n.LocaleContextHolder; 026import org.springframework.context.i18n.TimeZoneAwareLocaleContext; 027import org.springframework.lang.Nullable; 028 029/** 030 * A context that holds user-specific <code>java.time</code> (JSR-310) settings 031 * such as the user's Chronology (calendar system) and time zone. 032 * A {@code null} property value indicate the user has not specified a setting. 033 * 034 * @author Juergen Hoeller 035 * @since 4.0 036 * @see DateTimeContextHolder 037 */ 038public class DateTimeContext { 039 040 @Nullable 041 private Chronology chronology; 042 043 @Nullable 044 private ZoneId timeZone; 045 046 047 /** 048 * Set the user's chronology (calendar system). 049 */ 050 public void setChronology(@Nullable Chronology chronology) { 051 this.chronology = chronology; 052 } 053 054 /** 055 * Return the user's chronology (calendar system), if any. 056 */ 057 @Nullable 058 public Chronology getChronology() { 059 return this.chronology; 060 } 061 062 /** 063 * Set the user's time zone. 064 * <p>Alternatively, set a {@link TimeZoneAwareLocaleContext} on 065 * {@link LocaleContextHolder}. This context class will fall back to 066 * checking the locale context if no setting has been provided here. 067 * @see org.springframework.context.i18n.LocaleContextHolder#getTimeZone() 068 * @see org.springframework.context.i18n.LocaleContextHolder#setLocaleContext 069 */ 070 public void setTimeZone(@Nullable ZoneId timeZone) { 071 this.timeZone = timeZone; 072 } 073 074 /** 075 * Return the user's time zone, if any. 076 */ 077 @Nullable 078 public ZoneId getTimeZone() { 079 return this.timeZone; 080 } 081 082 083 /** 084 * Get the DateTimeFormatter with the this context's settings 085 * applied to the base {@code formatter}. 086 * @param formatter the base formatter that establishes default 087 * formatting rules, generally context-independent 088 * @return the contextual DateTimeFormatter 089 */ 090 public DateTimeFormatter getFormatter(DateTimeFormatter formatter) { 091 if (this.chronology != null) { 092 formatter = formatter.withChronology(this.chronology); 093 } 094 if (this.timeZone != null) { 095 formatter = formatter.withZone(this.timeZone); 096 } 097 else { 098 LocaleContext localeContext = LocaleContextHolder.getLocaleContext(); 099 if (localeContext instanceof TimeZoneAwareLocaleContext) { 100 TimeZone timeZone = ((TimeZoneAwareLocaleContext) localeContext).getTimeZone(); 101 if (timeZone != null) { 102 formatter = formatter.withZone(timeZone.toZoneId()); 103 } 104 } 105 } 106 return formatter; 107 } 108 109}