001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.juneau.commons.utils;
018
019import static org.apache.juneau.commons.utils.StringUtils.*;
020import static org.apache.juneau.commons.utils.ThrowableUtils.*;
021
022import java.time.format.*;
023
024import org.apache.juneau.commons.collections.*;
025
026/**
027 * A utility class for parsing and formatting HTTP dates as used in cookies and other headers.
028 *
029 * <p>
030 * This class handles dates as defined by RFC 2616 section 3.3.1 as well as some other common non-standard formats.
031 *
032 * <p>
033 * This class was copied from HttpClient 4.3.
034 *
035 */
036public class DateUtils {
037
038   private static final Cache<String, DateTimeFormatter> DATE_TIME_FORMATTER_CACHE = Cache.of(String.class, DateTimeFormatter.class)
039      .maxSize(100)
040      .supplier(pattern -> {
041         if (isEmpty(pattern))
042            return DateTimeFormatter.ISO_INSTANT;
043         try {
044            for (var f : DateTimeFormatter.class.getFields()) {
045               if (f.getName().equals(pattern)) {
046                  return (DateTimeFormatter)f.get(null);
047               }
048            }
049            return DateTimeFormatter.ofPattern(pattern);
050         } catch (IllegalArgumentException | IllegalAccessException e) {
051            throw toRex(e);
052         }
053      })
054      .build();
055
056   /**
057    * Returns a {@link DateTimeFormatter} using either a pattern or predefined pattern name.
058    *
059    * @param pattern The pattern (e.g. <js>"yyyy-MM-dd"</js>) or pattern name (e.g. <js>"ISO_INSTANT"</js>).
060    * @return The formatter.
061    */
062   public static DateTimeFormatter getDateTimeFormatter(String pattern) {
063      return DATE_TIME_FORMATTER_CACHE.get(pattern);
064   }
065}