检查字符串是否是日期

时间:2020-03-11 08:54:43

标签: javascript angular typescript

我有以下字符串:

a='Check 134', a='2020-01-15T10:47:54Z', a='1234', a= some object

我要检查字符串是否是日期。

我尝试过:

new Date(a) instanceof Date &&
        !isNaN(new Date(a).getTime())

,但是只要有数字,它就为a ='Check 123'返回true。

什么是更好的解决方案?

注意:由于项目限制,我不想使用momentjs

7 个答案:

答案 0 :(得分:2)

实际上,问题应该是:如何确定给定的字符串是否可以转换为真实的Date对象

现在,更多的东西可能会转换为Date(例如,尝试new Date("")new Date(0))。因此,您可能想对要转换的 使用自己的限制。这是一种将输入限制为实际Date对象或String对象的方法:

const canConvertToDate = trial => 
  [String, Date].includes(trial.constructor) && 
  !isNaN(new Date(trial));

console.log(`canConvertToDate(\`\`): ${canConvertToDate(``)}`);
console.log(`canConvertToDate(\`no dice\`): ${canConvertToDate(`no dice`)}`);
console.log(`canConvertToDate(new Date): ${canConvertToDate(new Date)}`);
console.log(`canConvertToDate(\`2020-03-03 00:00:00\`): ${
  canConvertToDate(`2020-03-03 00:00:00`)}`);
console.log(`canConvertToDate(0): ${canConvertToDate(0)}`);
console.log(`canConvertToDate(\`Wed, 11 Mar 2020 09:27:50 GMT\`): ${
  canConvertToDate(`Wed, 11 Mar 2020 09:27:50 GMT`)}`);
console.log(`canConvertToDate(new Date().toUTCString()): ${
  canConvertToDate(new Date().toUTCString())}`);
console.log(`canConvertToDate(134): ${canConvertToDate(134)}`);

// Please note the browser difference (Chrome / Firefox)
console.log(`canConvertToDate(\`134\`): ${canConvertToDate(`134`)}`);
.as-console-wrapper { top: 0; max-height: 100% !important; }

上一个代码段将不会始终为您提供所需的结果(请参阅注释)。

或者,您也可以编写某种解析器来确定给定的字符串是否可以转换为Date,以便更多(但不是100%)确定字符串可以转换为Date 。像这样:

console.log(`tryParseDate(\`\`): ${tryParseDate(``).date}`);
console.log(`tryParseDate(new Date): ${tryParseDate(new Date).date}`);
console.log(`tryParseDate(\`Wed, 11 Mar 2020 09:27:50 GMT\`): ${
  tryParseDate(`Wed, 11 Mar 2020 09:27:50 GMT`).date}`);
console.log(`tryParseDate(\`check 134\`): ${tryParseDate(`check 134`).date}`);
console.log(`tryParseDate(\`3-3-2005\`, \`ddmmyyyy\`): ${
  tryParseDate(`03-03-2005`, `ddmmyyyy`).date}`);
console.log(`tryParseDate(\`12-22-1998 22:22:10.345\`, \`mmddyyyy\`): ${
  tryParseDate(`12-22-1998 22:22:10.345`, `mmddyyyy`).date}`);
console.log(`tryParseDate(\`29-02-2019 22:22:10.345\`, \`ddmmyyyy\`): ${
  tryParseDate(`29-02-2019 22:22:10.345`, `ddmmyyyy`).date}`);

function tryParseDate(someString, format = `yyyymmdd`) {
  const invalid = {cando: false, date: new Date(`invalid`)};
  
  if (someString.constructor !== String) { return { ...invalid, date: `Invalid Date: input not a string` }; }
  
  const between = (val, lower, upper) => val >= lower && val <= upper;
  const d = someString.split(/[/\- T:.]/g);
  
  if (d.length < 3) { return {...invalid, date: `Invalid Date: can't split to anything useful`}; }
  
  const formats = format.match(/(yyyy)|(mm)|(dd)/gi);
  const values = {
      year: +d[formats.findIndex(v => v === `yyyy`)], 
      month: +d[formats.findIndex(v => v === `mm`)], 
      date: +d[formats.findIndex(v => v === `dd`)] };

  const cando = !isNaN(values.year) && values.year > 0 &&
                !isNaN(values.month) && between(values.month, 1, 12)
                !isNaN(values.date) && between(values.date, 1, 31);
  
  if (!cando) { 
    return {...invalid, date: `Invalid Date: the given value is not valid`}; 
  }
  
  const date2Parse = `${d[formats.findIndex(v => v=== `yyyy`)]}/${
      d[formats.findIndex(v => v=== `mm`)]}/${
        d[formats.findIndex(v => v=== `dd`)]} ${
          d.slice(3).map((v, i) => !i ? v : i > 2 ? `.${v}` : `:${v}`).join(``)}`;
  const parsed = new Date(date2Parse);
  const checkLeap = parsed.getMonth() + 1 === values.month;
  const error = `Impossible Date: ${
    !checkLeap ? `${values.year} not a leap year` : `parsing failed`}`;
  return isNaN(parsed) || !checkLeap 
    ? {...invalid, date: error}
    : {cando: true, date: parsed};
}
.as-console-wrapper { top: 0; max-height: 100% !important; }

答案 1 :(得分:1)

由于您已经知道要检查的日期的格式,因此使用的可能是momentjs并对照该格式进行检查

var moment = require("moment");
var res = moment("Check 123", "YYYY-MM-DD", true).isValid();
console.log(res);

答案 2 :(得分:0)

您可以尝试使用Date.parse(),然后检查一个正数(日期> 0)。 例如:

 var t = T()
        let contentView = ContentView().environmentObject(t)

        Timer.scheduledTimer(withTimeInterval: 2, repeats: true) { (timer) in
            t.a += 1
        }

https://jsfiddle.net/zmLbh0tu/

答案 3 :(得分:0)

这是一个内部使用Date.parse()的简单函数;当您将带有空格的字符串传递给@interface MyHTTPSessionManager : AFHTTPSessionManager // These three methods below have been marked as deprecated in AFNetworking, // we override them here and remove DEPRECATED_ATTRIBUTE to silence the // deprecated-warning. - (nullable NSURLSessionDataTask *)GET:(NSString *)URLString parameters:(nullable id)parameters success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure; - (nullable NSURLSessionDataTask *)POST:(NSString *)URLString parameters:(nullable id)parameters success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure; - (nullable NSURLSessionDataTask *)POST:(NSString *)URLString parameters:(nullable id)parameters constructingBodyWithBlock:(nullable void (^)(id <AFMultipartFormData> formData))block success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure; @end @implementation MyHTTPSessionManager - (nullable NSURLSessionDataTask *)GET:(NSString *)URLString parameters:(nullable id)parameters success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure { return [self GET:URLString parameters:parameters progress:nil success:success failure:failure]; } - (nullable NSURLSessionDataTask *)POST:(NSString *)URLString parameters:(nullable id)parameters success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure { return [self POST:URLString parameters:parameters progress:nil success:success failure:failure]; } - (nullable NSURLSessionDataTask *)POST:(NSString *)URLString parameters:(nullable id)parameters constructingBodyWithBlock:(nullable void (^)(id <AFMultipartFormData> formData))block success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure { return [self POST:URLString parameters:parameters constructingBodyWithBlock:block progress:nil success:success failure:failure]; } @end 时,它将忽略非数字字符并返回正数;因此,您需要先删除空格字符,然后再将其传递给Date.parse()

Date.parse()


编辑:Chrome中的Date还存在一些警告,因为它存在公开的问题,围绕它的讨论很多,请检查SO question chrome中棘手的极端情况;看来运行Chrome的最佳方法是知道您期望的输入类型并根据它进行验证。 (例如RFC 2822 / ISO 8601日期格式)。对于已知的日期格式,可以使用健壮的正则表达式来使用和确认,但是目前尝试在chrome中验证所有可用的日期格式存在很多极端情况和潜在的误报

答案 4 :(得分:0)

可以检查字符串是否包含yearmonthday。此外,我们可以添加一些条件以使用更严格的规则来定义字符串是否为Date

const isDate = str => {
    let [y,M,d,h,m,s] = str.split(/[- : T Z]/);
    return (y && M <= 12 && d <= 31) ? true : false;
} 

一个例子:

const isDate = str => {
    let [y,M,d,h,m,s] = str.split(/[- : T Z]/);
    return (y && M <= 12 && d <= 31) ? true : false;
}

console.log('Check 134', isDate('Check 134'))
console.log('2020-01-15T10:47:54Z', isDate('2020-01-15T10:47:54Z'))
console.log('1234', isDate('1234'))
console.log('13-13-13', isDate('13-13-13'))

答案 5 :(得分:-1)

您可以使用Date.parse()。如果它返回正值,那么它是有效的,否则无效。例如:-

Date.parse("2020-01-15T10:47:54Z")

答案 6 :(得分:-2)

只需使用typeof运算符。无需使用任何外部库。

if (typeof date === 'object') {
    // date is object
}
if (typeof date === 'string') {
//date is string
}