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