001/*
002 * oauth2-oidc-sdk
003 *
004 * Copyright 2012-2016, Connect2id Ltd and contributors.
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.oauth2.sdk.util.date;
019
020
021import java.util.Objects;
022import java.util.regex.Matcher;
023import java.util.regex.Pattern;
024
025import com.nimbusds.oauth2.sdk.ParseException;
026
027
028/**
029 * Simple date. Supports ISO 8601 formatting and parsing.
030 */
031public class SimpleDate {
032        
033        
034        /**
035         * The year.
036         */
037        private final int year;
038        
039        
040        /**
041         * The month.
042         */
043        private final int month;
044        
045        
046        /**
047         * The day of the month.
048         */
049        private final int day;
050        
051        
052        /**
053         * Creates a new simple date. No validation of month and day is
054         * performed.
055         *
056         * @param year  The year.
057         * @param month The month.
058         * @param day   The day of the month.
059         */
060        public SimpleDate(final int year, final int month, final int day) {
061                this.year = year;
062                this.month = month;
063                this.day = day;
064        }
065        
066        
067        /**
068         * Returns the year.
069         *
070         * @return The year.
071         */
072        public int getYear() {
073                return year;
074        }
075        
076        
077        /**
078         * Returns the month.
079         *
080         * @return The month.
081         */
082        public int getMonth() {
083                return month;
084        }
085        
086        
087        /**
088         * Returns the day of the month.
089         *
090         * @return The day of the month.
091         */
092        public int getDay() {
093                return day;
094        }
095        
096        
097        /**
098         * Returns an ISO 8601 representation in {@code YYYY-MM-DD} format.
099         *
100         * <p>Example: {@code 2019-11-01}
101         *
102         * @return The ISO 8601 representation.
103         */
104        public String toISO8601String() {
105                
106                return getYear() + "-" + (getMonth() < 10 ? "0" : "") + getMonth() + "-" + (getDay() < 10 ? "0" : "") + getDay();
107        }
108        
109        
110        @Override
111        public String toString() {
112                return toISO8601String();
113        }
114        
115        
116        @Override
117        public boolean equals(Object o) {
118                if (this == o) return true;
119                if (!(o instanceof SimpleDate)) return false;
120                SimpleDate that = (SimpleDate) o;
121                return getYear() == that.getYear() &&
122                        getMonth() == that.getMonth() &&
123                        getDay() == that.getDay();
124        }
125        
126        
127        @Override
128        public int hashCode() {
129                return Objects.hash(getYear(), getMonth(), getDay());
130        }
131        
132        
133        /**
134         * Parses an ISO 8601 representation in {@code YYYY-MM-DD} format.
135         *
136         * <p>Example: {@code 2019-11-01}
137         *
138         * @param s The string to parse.
139         *
140         * @return The simple date.
141         *
142         * @throws ParseException If parsing failed.
143         */
144        public static SimpleDate parseISO8601String(final String s)
145                throws ParseException {
146                
147                Pattern p = Pattern.compile("(\\d{4})-(\\d{2})-(\\d{2})");
148                Matcher m = p.matcher(s);
149                if (! m.matches()) {
150                        throw new ParseException("Invalid ISO 8601 date: YYYY-MM-DD");
151                }
152                return new SimpleDate(Integer.parseInt(m.group(1)), Integer.parseInt(m.group(2)), Integer.parseInt(m.group(3)));
153        }
154}