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 * Returns the current {@link Date}, with the milliseconds removed. 032 * 033 * @return The current {@link Date}, with seconds precision. 034 */ 035 public static Date nowWithSecondsPrecision() { 036 037 return fromSecondsSinceEpoch(toSecondsSinceEpoch(new Date())); 038 } 039 040 041 /** 042 * Converts the specified {@link Date} to seconds since the Unix epoch. 043 * 044 * @param date The {@link Date}. Must not be {@code null}. 045 * 046 * @return The seconds since the Unix epoch. 047 */ 048 public static long toSecondsSinceEpoch(final Date date) { 049 050 return date.getTime() / 1000L; 051 } 052 053 054 /** 055 * Converts the specified seconds since the Unix epoch to a 056 * {@link Date}. 057 * 058 * @param time The seconds since the Unix epoch. Must not be negative. 059 * 060 * @return The {@link Date}. 061 */ 062 public static Date fromSecondsSinceEpoch(final long time) { 063 064 return new Date(time * 1000L); 065 } 066 067 068 /** 069 * Check if the specified {@link Date} is after the specified 070 * reference, given the maximum accepted negative clock skew. 071 * 072 * <p>Formula: 073 * 074 * <pre> 075 * return date + clock_skew > reference 076 * </pre> 077 * 078 * Example: Ensure a JWT expiration (exp) timestamp is after the 079 * current time, with a minute of acceptable clock skew. 080 * 081 * <pre> 082 * boolean valid = DateUtils.isAfter(exp, new Date(), 60); 083 * </pre> 084 * 085 * @param date The {@link Date} to check. Must not be 086 * {@code null}. 087 * @param reference The reference {@link Date} (e.g. the 088 * current time). Must not be {@code null}. 089 * @param maxClockSkewSeconds The maximum acceptable negative clock 090 * skew of the date value to check, in 091 * seconds. 092 * 093 * @return {@code true} if the {@link Date} is before the reference, 094 * plus the maximum accepted clock skew, else {@code false}. 095 */ 096 public static boolean isAfter(final Date date, 097 final Date reference, 098 final long maxClockSkewSeconds) { 099 100 return new Date(date.getTime() + maxClockSkewSeconds*1000L).after(reference); 101 } 102 103 104 /** 105 * Checks if the specified {@link Date} is before the specified 106 * reference, given the maximum accepted positive clock skew. 107 * 108 * <p>Formula: 109 * 110 * <pre> 111 * return date - clock_skew < reference 112 * </pre> 113 * 114 * Example: Ensure a JWT issued-at (iat) timestamp is before the 115 * current time, with a minute of acceptable clock skew. 116 * 117 * <pre> 118 * boolean valid = DateUtils.isBefore(iat, new Date(), 60); 119 * </pre> 120 * 121 * @param date The {@link Date} to check. Must not be 122 * {@code null}. 123 * @param reference The reference {@link Date} (e.g. the 124 * current time). Must not be {@code null}. 125 * @param maxClockSkewSeconds The maximum acceptable clock skew of the 126 * date value to check, in seconds. 127 * 128 * @return {@code true} if the {@link Date} is before the reference, 129 * minus the maximum accepted clock skew, else {@code false}. 130 */ 131 public static boolean isBefore(final Date date, 132 final Date reference, 133 final long maxClockSkewSeconds) { 134 135 return new Date(date.getTime() - maxClockSkewSeconds*1000L).before(reference); 136 } 137 138 139 /** 140 * Checks if the specified {@link Date} is within the specified 141 * reference, give or take the maximum accepted clock skew. 142 * 143 * @param date The {@link Date} to check. Must not be 144 * {@code null}. 145 * @param reference The reference {@link Date} (e.g. the 146 * current time). Must not be {@code null}. 147 * @param maxClockSkewSeconds The maximum acceptable clock skew of the 148 * date value to check, in seconds. 149 * 150 * @return {@code true} if the {@link Date} is within the reference, 151 * give or take the maximum accepted clock skew, else 152 * {@code false}. 153 */ 154 public static boolean isWithin(final Date date, 155 final Date reference, 156 final long maxClockSkewSeconds) { 157 158 long minTime = reference.getTime() - maxClockSkewSeconds*1000L; 159 long maxTime = reference.getTime() + maxClockSkewSeconds*1000L; 160 161 return date.getTime() > minTime && date.getTime() < maxTime; 162 } 163 164 165 /** 166 * Prevents instantiation. 167 */ 168 private DateUtils() { } 169}