All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.jsonwebtoken.impl.lang.JwtDateConverter Maven / Gradle / Ivy

/*
 * Copyright © 2021 jsonwebtoken.io
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package io.jsonwebtoken.impl.lang;

import io.jsonwebtoken.lang.DateFormats;

import java.text.ParseException;
import java.util.Calendar;
import java.util.Date;

public class JwtDateConverter implements Converter {

    public static final JwtDateConverter INSTANCE = new JwtDateConverter();

    @Override
    public Object applyTo(Date date) {
        if (date == null) {
            return null;
        }
        // https://www.rfc-editor.org/rfc/rfc7519.html#section-2, 'Numeric Date' definition:
        return date.getTime() / 1000L;
    }

    @Override
    public Date applyFrom(Object o) {
        return toSpecDate(o);
    }

    /**
     * Returns an RFC-compatible {@link Date} equivalent of the specified object value using heuristics.
     *
     * @param value object to convert to a {@code Date} using heuristics.
     * @return an RFC-compatible {@link Date} equivalent of the specified object value using heuristics.
     * @since 0.10.0
     */
    public static Date toSpecDate(Object value) {
        if (value == null) {
            return null;
        }
        if (value instanceof String) {
            try {
                value = Long.parseLong((String) value);
            } catch (NumberFormatException ignored) { // will try in the fallback toDate method call below
            }
        }
        if (value instanceof Number) {
            // https://github.com/jwtk/jjwt/issues/122:
            // The JWT RFC *mandates* NumericDate values are represented as seconds.
            // Because java.util.Date requires milliseconds, we need to multiply by 1000:
            long seconds = ((Number) value).longValue();
            value = seconds * 1000;
        }
        //v would have been normalized to milliseconds if it was a number value, so perform normal date conversion:
        return toDate(value);
    }

    /**
     * Returns a {@link Date} equivalent of the specified object value using heuristics.
     *
     * @param v the object value to represent as a Date.
     * @return a {@link Date} equivalent of the specified object value using heuristics.
     */
    public static Date toDate(Object v) {
        if (v == null) {
            return null;
        } else if (v instanceof Date) {
            return (Date) v;
        } else if (v instanceof Calendar) { //since 0.10.0
            return ((Calendar) v).getTime();
        } else if (v instanceof Number) {
            //assume millis:
            long millis = ((Number) v).longValue();
            return new Date(millis);
        } else if (v instanceof String) {
            return parseIso8601Date((String) v); //ISO-8601 parsing since 0.10.0
        } else {
            String msg = "Cannot create Date from object of type " + v.getClass().getName() + ".";
            throw new IllegalArgumentException(msg);
        }
    }

    /**
     * Parses the specified ISO-8601-formatted string and returns the corresponding {@link Date} instance.
     *
     * @param value an ISO-8601-formatted string.
     * @return a {@link Date} instance reflecting the specified ISO-8601-formatted string.
     * @since 0.10.0
     */
    private static Date parseIso8601Date(String value) throws IllegalArgumentException {
        try {
            return DateFormats.parseIso8601Date(value);
        } catch (ParseException e) {
            String msg = "String value is not a JWT NumericDate, nor is it ISO-8601-formatted. " +
                    "All heuristics exhausted. Cause: " + e.getMessage();
            throw new IllegalArgumentException(msg, e);
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy