Completed
Push — master ( 0bb17e...5a7e4d )
by Sebastian
04:41
created

DateHelper   A

Complexity

Total Complexity 21

Size/Duplication

Total Lines 94
Duplicated Lines 0 %

Coupling/Cohesion

Components 0
Dependencies 2

Importance

Changes 0
Metric Value
dl 0
loc 94
rs 10
c 0
b 0
f 0
wmc 21
lcom 0
cbo 2

4 Methods

Rating   Name   Duplication   Size   Complexity  
A serializeDate() 0 8 4
A parseDateParts() 0 14 3
C getSortKeyDate() 0 23 7
B hasDateRanges() 0 15 7
1
<?php
2
/*
3
 * citeproc-php
4
 *
5
 * @link        http://github.com/seboettg/citeproc-php for the source repository
6
 * @copyright   Copyright (c) 2016 Sebastian Böttger.
7
 * @license     https://opensource.org/licenses/MIT
8
 */
9
10
namespace Seboettg\CiteProc\Util;
11
use Seboettg\CiteProc\Exception\CiteProcException;
12
use Seboettg\CiteProc\Style\Sort\Key;
13
14
15
/**
16
 * Class Date
17
 *
18
 * Just a helper class for date issues
19
 *
20
 * @package Seboettg\CiteProc\Util
21
 *
22
 * @author Sebastian Böttger <[email protected]>
23
 */
24
class DateHelper
25
{
26
27
    /**
28
     * dates: Date variables called via the variable attribute are returned in the YYYYMMDD format, with zeros
29
     * substituted for any missing date-parts (e.g. 20001200 for December 2000). As a result, less specific dates
30
     * precede more specific dates in ascending sorts, e.g. “2000, May 2000, May 1st 2000”. Negative years are sorted
31
     * inversely, e.g. “100BC, 50BC, 50AD, 100AD”. Seasons are ignored for sorting, as the chronological order of the
32
     * seasons differs between the northern and southern hemispheres.
33
     *
34
     * @param array $dateParts
35
     * @return string
36
     */
37
    public static function serializeDate($dateParts)
38
    {
39
        $year  = isset($dateParts[0]) ? $dateParts[0] : "0000";
40
        $month = isset($dateParts[1]) ? $dateParts[1] : "00";
41
        $day = isset($dateParts[2]) ? $dateParts[2] : "00";
42
43
        return sprintf("%04d%02d%02d", $year, $month, $day);
44
    }
45
46
    /**
47
     * @param $date
48
     * @return array
49
     * @throws CiteProcException
50
     */
51
    public static function parseDateParts($date)
52
    {
53
        if (!isset($date->{'raw'})) {
54
            return [];
55
        }
56
        try {
57
            $dateTime = new \DateTime($date->{'raw'});
58
            $arr = [[$dateTime->format("Y"), $dateTime->format("m"), $dateTime->format("d")]];
59
        } catch (\Exception $e) {
60
            throw new CiteProcException("Could not parse date \"" . $date->{'raw'} . "\".", 0, $e);
61
        }
62
63
        return $arr;
64
    }
65
66
    /**
67
     * creates sort key for variables containing date and date ranges
68
     * @param array $dataItem
69
     * @param Key $key
70
     * @return string
71
     */
72
    public static function getSortKeyDate($dataItem, $key)
73
    {
74
        $variable = $variable = $key->getVariable();
75
        $part = $key->getRangePart();
76
        if (count($dataItem->{$variable}->{'date-parts'}) > 1) {
77
            //Date range
78
            $datePart = $dataItem->{$variable}->{'date-parts'}[$part];
79
            $sortKey = self::serializeDate($datePart);
80
            if ($key->getSort() === "descending" && $part === 0 ||
81
                $key->getSort() === "ascending" && $part === 1) {
82
                $sortKey .= "-";
83
            }
84
        } else {
85
86
            if (!isset($dataItem->{$variable}->{'date-parts'})) {
87
                $dateParts = self::parseDateParts($dataItem->{$variable});
88
            } else {
89
                $dateParts = $dataItem->{$variable}->{'date-parts'}[0];
90
            }
91
            $sortKey = self::serializeDate($dateParts);
92
        }
93
        return $sortKey;
94
    }
95
96
    /**
97
     * @param array $items
98
     * @param string $variable name of the date variable
99
     * @param string $match ("all"|"any") default "all"
100
     * @return bool
101
     */
102
    public static function hasDateRanges($items, $variable, $match = "all")
103
    {
104
        $ret = true;
105
        foreach ($items as $item) {
106
            $dateParts = $item->{$variable}->{"date-parts"};
107
            if ($match === "all" && count($dateParts) !== 2) {
108
                return false;
109
            } else if ($match === "any" && count($dateParts) === 2) {
110
                return true;
111
            } else {
112
                $ret = ($match === "all") ? $ret & true : $ret | true;
113
            }
114
        }
115
        return boolval($ret);
116
    }
117
}