001/*
002 * nimbus-jose-jwt
003 *
004 * Copyright 2012-2016, Connect2id Ltd.
005 *
006 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use
007 * this file except in compliance with the License. You may obtain a copy of the
008 * License at
009 *
010 *    http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software distributed
013 * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
014 * CONDITIONS OF ANY KIND, either express or implied. See the License for the
015 * specific language governing permissions and limitations under the License.
016 */
017
018package com.nimbusds.jwt.util;
019
020
021import java.util.Date;
022
023
024/**
025 * Date utilities.
026 */
027public class DateUtils {
028
029
030        /**
031         * Converts the specified date object to a Unix epoch time in seconds.
032         *
033         * @param date The date. Must not be {@code null}.
034         *
035         * @return The Unix epoch time, in seconds.
036         */
037        public static long toSecondsSinceEpoch(final Date date) {
038
039                return date.getTime() / 1000L;
040        }
041
042
043        /**
044         * Converts the specified Unix epoch time in seconds to a date object.
045         *
046         * @param time The Unix epoch time, in seconds. Must not be negative.
047         *
048         * @return The date.
049         */
050        public static Date fromSecondsSinceEpoch(final long time) {
051
052                return new Date(time * 1000L);
053        }
054
055
056        /**
057         * Check if the specified date is after the specified reference, given
058         * the maximum accepted negative clock skew.
059         *
060         * <p>Formula:
061         *
062         * <pre>
063         * return date + clock_skew &gt; reference
064         * </pre>
065         *
066         * Example: Ensure a JWT expiration (exp) timestamp is after the
067         * current time, with a minute of acceptable clock skew.
068         *
069         * <pre>
070         * boolean valid = DateUtils.isAfter(exp, new Date(), 60);
071         * </pre>
072         *
073         * @param date                The date to check. Must not be
074         *                            {@code null}.
075         * @param reference           The reference date (e.g. the current
076         *                            time). Must not be {@code null}.
077         * @param maxClockSkewSeconds The maximum acceptable negative clock
078         *                            skew of the date value to check, in
079         *                            seconds.
080         *
081         * @return {@code true} if the date is before the reference, plus the
082         *         maximum accepted clock skew, else {@code false}.
083         */
084        public static boolean isAfter(final Date date,
085                                      final Date reference,
086                                      final long maxClockSkewSeconds) {
087
088                return new Date(date.getTime() + maxClockSkewSeconds*1000L).after(reference);
089        }
090
091
092        /**
093         * Checks if the specified date is before the specified reference,
094         * given the maximum accepted positive clock skew.
095         *
096         * <p>Formula:
097         *
098         * <pre>
099         * return date - clock_skew &lt; reference
100         * </pre>
101         *
102         * Example: Ensure a JWT issued-at (iat) timestamp is before the
103         * current time, with a minute of acceptable clock skew.
104         *
105         * <pre>
106         * boolean valid = DateUtils.isBefore(iat, new Date(), 60);
107         * </pre>
108         *
109         * @param date                The date to check. Must not be
110         *                            {@code null}.
111         * @param reference           The reference date (e.g. the current
112         *                            time). Must not be {@code null}.
113         * @param maxClockSkewSeconds The maximum acceptable clock skew of the
114         *                            date value to check, in seconds.
115         *
116         * @return {@code true} if the date is before the reference, minus the
117         *         maximum accepted clock skew, else {@code false}.
118         */
119        public static boolean isBefore(final Date date,
120                                       final Date reference,
121                                       final long maxClockSkewSeconds) {
122
123                return new Date(date.getTime() - maxClockSkewSeconds*1000L).before(reference);
124        }
125        
126        
127        /**
128         * Checks if the specified date is within the specified reference,
129         * give or take the maximum accepted clock skew.
130         *
131         * @param date                The date to check. Must not be
132         *                            {@code null}.
133         * @param reference           The reference date (e.g. the current
134         *                            time). Must not be {@code null}.
135         * @param maxClockSkewSeconds The maximum acceptable clock skew of the
136         *                            date value to check, in seconds.
137         *
138         * @return {@code true} if the date is within the reference, give or
139         *         take the maximum accepted clock skew, else {@code false}.
140         */
141        public static boolean isWithin(final Date date,
142                                       final Date reference,
143                                       final long maxClockSkewSeconds) {
144                
145                long minTime = reference.getTime() - maxClockSkewSeconds*1000L;
146                long maxTime = reference.getTime() + maxClockSkewSeconds*1000L;
147                
148                return date.getTime() > minTime && date.getTime() < maxTime;
149        }
150
151
152        /**
153         * Prevents instantiation.
154         */
155        private DateUtils() { }
156}