001/*
002 * This file is part of the JDrupes non-blocking HTTP Codec
003 * Copyright (C) 2017 Michael N. Lipp
004 *
005 * This program is free software; you can redistribute it and/or modify it 
006 * under the terms of the GNU Lesser General Public License as published
007 * by the Free Software Foundation; either version 3 of the License, or 
008 * (at your option) any later version.
009 *
010 * This program is distributed in the hope that it will be useful, but 
011 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
012 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 
013 * License for more details.
014 *
015 * You should have received a copy of the GNU Lesser General Public License along 
016 * with this program; if not, see <http://www.gnu.org/licenses/>.
017 */
018
019package org.jdrupes.httpcodec.types;
020
021import java.text.ParseException;
022import java.time.Instant;
023import java.time.Year;
024import java.time.ZoneId;
025import java.time.format.DateTimeFormatter;
026import java.time.format.DateTimeFormatterBuilder;
027import java.time.format.DateTimeParseException;
028import java.time.temporal.ChronoField;
029import java.util.Locale;
030
031/**
032 * A converter that converts between date/time representatiosn and
033 * {@link Instant}.
034 */
035public class InstantConverter implements Converter<Instant> {
036
037        // "Sunday, 06-Nov-94 08:49:37 GMT"
038        private static final DateTimeFormatter RFC_850_DATE_TIME
039                = new DateTimeFormatterBuilder().appendPattern("EEEE, dd-MMM-")
040                .appendValueReduced(ChronoField.YEAR, 2, 2, Year.now().getValue() - 50)
041                .appendPattern(" HH:mm:ss zz")
042                .toFormatter().withZone(ZoneId.of("GMT"))
043                .withLocale(Locale.US);
044        // "Sun Nov  6 08:49:37 1994"
045        private static final DateTimeFormatter ANSI_DATE_TIME
046                = DateTimeFormatter.ofPattern("EEE MMM ppd HH:mm:ss yyyy", Locale.US)
047                .withZone(ZoneId.of("GMT"));
048
049        @Override
050        public String asFieldValue(Instant value) {
051                return DateTimeFormatter.RFC_1123_DATE_TIME.format(
052                                value.atZone(ZoneId.of("GMT")));        
053        }
054
055        @Override
056        public Instant fromFieldValue(String text) throws ParseException {
057                try {
058                        return Instant.from(
059                                        DateTimeFormatter.RFC_1123_DATE_TIME.parse(text));
060                } catch (DateTimeParseException e) {
061                        try {
062                                return Instant.from(RFC_850_DATE_TIME.parse(text));
063                        } catch (DateTimeParseException e1) {
064                                try {
065                                        return Instant.from(ANSI_DATE_TIME.parse(text));
066                                } catch (DateTimeParseException e2) {
067                                        throw new ParseException(text, 0);
068                                }
069                        }
070                }
071        }
072}