Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/276.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用PHP进行高级日期验证_Php_Validation_Date - Fatal编程技术网

使用PHP进行高级日期验证

使用PHP进行高级日期验证,php,validation,date,Php,Validation,Date,我必须用我当前的项目验证许多日期。不幸的是,这些日期可能差异很大。例子包括: 1983-07-10(1970年后) 1492-10-11(1970年之前,Unix时间戳的年份-这消除了某些系统上的strotime()) 公元前200年(非常古老…) 日期不会超过公元前9999年,也不会是未来的(超过“今天”)。验证提交的值是否确实是日期和正确日期的最佳方法是什么 更新… 所有日期必须在其全局列表中可排序。意味着上述日期1和3必须相互比较,并按ASC或DESC排序 我完全了解过去发生的日历变化,以

我必须用我当前的项目验证许多日期。不幸的是,这些日期可能差异很大。例子包括:

  • 1983-07-10(1970年后)
  • 1492-10-11(1970年之前,Unix时间戳的年份-这消除了某些系统上的strotime())
  • 公元前200年(非常古老…)
  • 日期不会超过公元前9999年,也不会是未来的(超过“今天”)。验证提交的值是否确实是日期和正确日期的最佳方法是什么

    更新…

    所有日期必须在其全局列表中可排序。意味着上述日期1和3必须相互比较,并按ASC或DESC排序


    我完全了解过去发生的日历变化,以及这些变化带来的混乱。我的项目假设用户已经执行了适当的校准,以根据我们的现代日历系统找出日期。我不会为它们执行此校准。

    关于strotime()呢?

    一系列精心编写的正则表达式如何识别每种可能的格式。一旦您知道了格式,您就可以验证它,并可能将其放入统一的表示(例如,64位时间)

    e、 g

    因为听起来每个表单都有自己的验证规则,而且您没有实现任何广泛使用的标准,所以我认为您需要分别验证每个案例

    更新:

    所有日期必须在其全局列表中可排序


    在我看来,为了能够对以不同格式出现的日期进行排序,您需要对每个日期进行统一的内部表示,正如我前面提到的。例如,使用多键字典(STD: C++中的MultIMPAP,不确定PHP)来存储(统一表示)->(输入表示)映射。根据容器的实现,您可以免费获得反向查找或密钥排序。

    我认为,最重要的是列出所有可能性(或以某种方式将它们分组)并为每个选项准备正则表达式,并在此基础上识别并处理它。

    < P>您可以考虑实现自己的自定义DATETYPE类型类。我不确定您的所有需求是什么,但我可以看到它具有BC/AD、格式等属性。稍微考虑一下,如果您熟悉货币类型类,那么它应该不会比实现货币类型类困难多少


    我提出这一建议的原因是公元前200年和1492-10-07年有着巨大的不同,甚至在格式上也是如此。即兴说,如果你治疗BC<0使用Zend_Date怎么样。是一个非常好的日期实用程序库。它可以独立工作,也可以与其他Zend库一起工作,还可以与date_default_timezone_set()一起工作,因此会自动为设置的时区解析日期,并且它将适用于Unix时间戳范围之外的日期。有时写起来可能有点冗长,但它的优点远远大于缺点

    您可能必须为BC/AD实现自己的自定义解析,因为我不确定它是否适用于此,但可能值得一试

    这可能值得一看,然而,我还没有使用过它,并且从很多人那里听说他们更喜欢Zend_Date而不是Pear的Date套餐


    你可以自己写,但为什么要重新发明轮子呢。如果它没有按你想要的方式滚动,那么接受它并加以改进;)

    由于您控制输入接口,在不丧失通用性的情况下,我们可以假设将有单独的年/月/日整数(正确验证…是否为整数:)。假设这一年将是负的,以表示BC

    所以首先。。。显而易见的(部分)答案是:。正如函数文档所说,这对于>=1年来说是很好的


    因此,在Jonathan的问题更新之后,如果第二个答案是的话,你就陷入了该怎么办的问题中:

    要进行简单的日期比较,您需要使用整数之类的东西,或者使用支持追溯到公元前9999年的类库(我不知道有这样的类库)

    您可以简单地将时间指定为自公元前1/1/10000(滚动您自己的历元)起的秒数;64位就足够了。要做到这一点,你需要解决一两个问题

    A.如何在PHP中执行64位整数

    PHP保证为整数提供31位。因此,您可以执行以下操作之一:

  • 编写您自己的62位整数类,该类将位存储在两个私有整数成员中。62位也足够了

    这将是痛苦的,而且可能很快主要优势:您不会依赖任何PHP扩展。

  • 使用或执行任意精度整数

    如果便携性不是必须的,我会先试试这个。不过,这可能会被证明慢于可接受的速度主要优势:您不会冒着出错的风险。

  • 有了60位左右的integer类(通过相应的方法或助手函数支持加法/减法/比较),您就可以编写一个CustomDateTime类,它支持您所需的所有逻辑。该类将包括所有“日期到整数”代码,反之亦然(如施工);所有需要执行int实现操作(例如比较)的代码都将被简单地转发到integer类

    B.如何在数据库中执行64位整数


    所有数据库都能做到这一点。不过,您几乎肯定需要这样做,因为MySQL不支持公元1000年之前的日期。不知道其他供应商的情况。

    日期输入格式是什么?答案在很大程度上取决于此。:)我愿意听取建议。我不确定我是否会有一系列的下拉列表,其中有一个额外的“B.C./a.D.”或一个简单的文本框;总而言之,BC/AD的单选按钮
    /(\d{4})-(\d{2})-(\d{2})/
    /(\d+)(bc|b.c.|bce|b.c.e)/i
    etc.
    
    define('YEAR_JULIAN_CALENDAR_INTRODUCED', -45);
    define('YEAR_JULIAN_CALENDAR_LEAP_IMPLEMENTED_CORRECTLY', 8);
    define('YEAR_GREGORIAN_CALENDAR_INTRODUCED', 1582);
    
    function is_leap_year($year) {
        if($year < YEAR_JULIAN_CALENDAR_INTRODUCED) {
            return false; // or good luck :)
        }
        if($year < YEAR_JULIAN_CALENDAR_LEAP_IMPLEMENTED_CORRECTLY) {
            return $year <= -9 && $year % 3 == 0;
        }
        if($year < YEAR_GREGORIAN_CALENDAR_INTRODUCED) {
            return $year % 4 == 0;
        }
        // Otherwise, Gregorian is in effect
        return $year % 4 == 0 && ($year % 100 != 0 || $year % 400 == 0);
    }