1 /* 2 * Copyright 2022 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package androidx.appsearch.utils; 18 19 import static androidx.annotation.RestrictTo.Scope.LIBRARY; 20 21 import androidx.annotation.RestrictTo; 22 23 import org.jspecify.annotations.NonNull; 24 25 import java.text.DateFormat; 26 import java.text.ParseException; 27 import java.text.SimpleDateFormat; 28 import java.util.Date; 29 import java.util.Locale; 30 31 /** 32 * Helper class used to validate date time formats. 33 * 34 * @exportToFramework:hide 35 */ 36 @RestrictTo(LIBRARY) 37 public final class DateTimeFormatValidator { DateTimeFormatValidator()38 private DateTimeFormatValidator() {} 39 40 /** 41 * Returns true if the date string matches yyyy-MM-dd 42 */ validateISO8601Date(@onNull String dateString)43 public static boolean validateISO8601Date(@NonNull String dateString) { 44 return validateDateFormat("yyyy-MM-dd", dateString); 45 } 46 47 /** 48 * Returns true if the date string matches yyyy-MM-ddTHH:mm:ss 49 */ validateISO8601DateTime(@onNull String dateString)50 public static boolean validateISO8601DateTime(@NonNull String dateString) { 51 return validateDateFormat("yyyy-MM-dd'T'HH:mm", dateString) 52 || validateDateFormat("yyyy-MM-dd'T'HH:mm:ss", dateString); 53 } 54 55 /** 56 * Returns true if the date string matches the provided format exactly. 57 */ validateDateFormat(@onNull String format, @NonNull String dateString)58 public static boolean validateDateFormat(@NonNull String format, @NonNull String dateString) { 59 // ISO 8601 DateTime format must be represented using arabic numerals (0-9). en-US is 60 // one of many locales that uses arabic numerals, therefore it is used during formatting. 61 // Even if the user's device is not in the en-US locale, this will still work since ISO 62 // 8601 is an international standard, and does not change based on locales. 63 DateFormat dateFormat = new SimpleDateFormat(format, Locale.US); 64 dateFormat.setLenient(false); 65 try { 66 Date date = dateFormat.parse(dateString); 67 // ensure exact match 68 if (date == null || !dateString.equals(dateFormat.format(date))) { 69 return false; 70 } 71 } catch (ParseException e) { 72 return false; 73 } 74 75 return true; 76 } 77 } 78