001/* 002 * Copyright 2002-2018 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.format.DateTimeFormatter; 020import java.util.Locale; 021 022import org.springframework.core.NamedThreadLocal; 023import org.springframework.lang.Nullable; 024 025/** 026 * A holder for a thread-local user {@link DateTimeContext}. 027 * 028 * @author Juergen Hoeller 029 * @since 4.0 030 * @see org.springframework.context.i18n.LocaleContextHolder 031 */ 032public final class DateTimeContextHolder { 033 034 private static final ThreadLocal<DateTimeContext> dateTimeContextHolder = 035 new NamedThreadLocal<>("DateTimeContext"); 036 037 038 private DateTimeContextHolder() { 039 } 040 041 042 /** 043 * Reset the DateTimeContext for the current thread. 044 */ 045 public static void resetDateTimeContext() { 046 dateTimeContextHolder.remove(); 047 } 048 049 /** 050 * Associate the given DateTimeContext with the current thread. 051 * @param dateTimeContext the current DateTimeContext, 052 * or {@code null} to reset the thread-bound context 053 */ 054 public static void setDateTimeContext(@Nullable DateTimeContext dateTimeContext) { 055 if (dateTimeContext == null) { 056 resetDateTimeContext(); 057 } 058 else { 059 dateTimeContextHolder.set(dateTimeContext); 060 } 061 } 062 063 /** 064 * Return the DateTimeContext associated with the current thread, if any. 065 * @return the current DateTimeContext, or {@code null} if none 066 */ 067 @Nullable 068 public static DateTimeContext getDateTimeContext() { 069 return dateTimeContextHolder.get(); 070 } 071 072 073 /** 074 * Obtain a DateTimeFormatter with user-specific settings applied to the given base Formatter. 075 * @param formatter the base formatter that establishes default formatting rules 076 * (generally user independent) 077 * @param locale the current user locale (may be {@code null} if not known) 078 * @return the user-specific DateTimeFormatter 079 */ 080 public static DateTimeFormatter getFormatter(DateTimeFormatter formatter, @Nullable Locale locale) { 081 DateTimeFormatter formatterToUse = (locale != null ? formatter.withLocale(locale) : formatter); 082 DateTimeContext context = getDateTimeContext(); 083 return (context != null ? context.getFormatter(formatterToUse) : formatterToUse); 084 } 085 086}