# 9155-判断日期有效性

# 题目描述

Implement a type ValidDate, which takes an input type T and returns whether T is a valid date.

Leap year is not considered

Good Luck!

ValidDate<'0102'>; // true
ValidDate<'0131'>; // true
ValidDate<'1231'>; // true
ValidDate<'0229'>; // false
ValidDate<'0100'>; // false
ValidDate<'0132'>; // false
ValidDate<'1301'>; // false

# 分析

要判断日期有效性,需要具备几个条件:

  1. 字符长度 = 4
  2. 月份必须是 01 - 12 之间
  3. 日期,根据不同的月份,需要在 01 - 31(1, 3, 5, 7, 8, 10, 12 月),或者 01 - 30(3, 6, 9, 11 月) 或 01 - 28(2 月份)

在 之前的 4425-实现比较 中实现过两个数字的比较,将月份和日期转成数字后,可以通过比较完成判断。

而在 651-字符长度 2 中实现过字符长度的判断,可以用于完成第一个条件的校验。

# 题解

// [651-字符长度2](/hard/651-字符长度2.md)
type LengthOfString<
  S extends string,
  Arr extends any[] = [],
> = S extends `${string}${infer R}`
  ? LengthOfString<R, [...Arr, 1]>
  : Arr['length'];

// [4425-实现比较](/medium/4425-实现比较.md)
// 进行了改造,相等时也返回 true
type GreaterEqualThan<
  T extends number,
  U extends number,
  Arr extends any[] = [],
> = T extends Arr['length']
  ? U extends Arr['length']
    ? true
    : false
  : U extends Arr['length']
  ? true
  : GreaterEqualThan<T, U, [...Arr, 1]>;

// 300-stringToNumber,进行了改造,支持了 01,这样开头为 0 的字符
type ToNumber<T extends string> = T extends `0${infer R}`
  ? ToNumber<R>
  : T extends `${infer F extends number}`
  ? F
  : 0;

// 记录月份对应关系
type Map = {
  1: 31;
  2: 28;
  3: 31;
  4: 30;
  5: 31;
  6: 30;
  7: 31;
  8: 31;
  9: 30;
  10: 31;
  11: 30;
  12: 31;
};

// 长度是否等于 4
type Condition1<T extends string> = LengthOfString<T> extends 4 ? true : false;

// 月份是否小于 12
type Condition2<T extends number> = T extends 0
  ? false
  : GreaterEqualThan<12, T>;

// 日期是否小于对应月份的日期
type Condition3<T extends number, Max extends number> = T extends 0
  ? false
  : GreaterEqualThan<Max, T>;

// 获取前两个字符
type GetFirstTwo<T extends string> =
  T extends `${infer A}${infer B}${string}${string}` ? `${A}${B}` : never;

// 获取后两个字符
type GetLastTwo<T extends string> =
  T extends `${string}${string}${infer C}${infer D}` ? `${C}${D}` : never;

type ValidDate<T extends string> = Condition1<T> extends true
  ? Condition2<ToNumber<GetFirstTwo<T>>> extends true
    ? Condition3<
        ToNumber<GetLastTwo<T>>,
        ToNumber<GetFirstTwo<T>> extends keyof Map
          ? Map[ToNumber<GetFirstTwo<T>>]
          : never
      > extends true
      ? true
      : false
    : false
  : false;

# 知识点

本题目虽然比较长,但是都是以前用过的判断,算是麻烦但不困难。

Last Updated: 2023/5/16 06:00:28