1/*
2Package date provides time.Time derivatives that conform to the Swagger.io (https://swagger.io/)
3defined date   formats: Date and DateTime. Both types may, in most cases, be used in lieu of
4time.Time types. And both convert to time.Time through a ToTime method.
5*/
6package date
7
8// Copyright 2017 Microsoft Corporation
9//
10//  Licensed under the Apache License, Version 2.0 (the "License");
11//  you may not use this file except in compliance with the License.
12//  You may obtain a copy of the License at
13//
14//      http://www.apache.org/licenses/LICENSE-2.0
15//
16//  Unless required by applicable law or agreed to in writing, software
17//  distributed under the License is distributed on an "AS IS" BASIS,
18//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19//  See the License for the specific language governing permissions and
20//  limitations under the License.
21
22import (
23	"fmt"
24	"time"
25)
26
27const (
28	fullDate     = "2006-01-02"
29	fullDateJSON = `"2006-01-02"`
30	dateFormat   = "%04d-%02d-%02d"
31	jsonFormat   = `"%04d-%02d-%02d"`
32)
33
34// Date defines a type similar to time.Time but assumes a layout of RFC3339 full-date (i.e.,
35// 2006-01-02).
36type Date struct {
37	time.Time
38}
39
40// ParseDate create a new Date from the passed string.
41func ParseDate(date string) (d Date, err error) {
42	return parseDate(date, fullDate)
43}
44
45func parseDate(date string, format string) (Date, error) {
46	d, err := time.Parse(format, date)
47	return Date{Time: d}, err
48}
49
50// MarshalBinary preserves the Date as a byte array conforming to RFC3339 full-date (i.e.,
51// 2006-01-02).
52func (d Date) MarshalBinary() ([]byte, error) {
53	return d.MarshalText()
54}
55
56// UnmarshalBinary reconstitutes a Date saved as a byte array conforming to RFC3339 full-date (i.e.,
57// 2006-01-02).
58func (d *Date) UnmarshalBinary(data []byte) error {
59	return d.UnmarshalText(data)
60}
61
62// MarshalJSON preserves the Date as a JSON string conforming to RFC3339 full-date (i.e.,
63// 2006-01-02).
64func (d Date) MarshalJSON() (json []byte, err error) {
65	return []byte(fmt.Sprintf(jsonFormat, d.Year(), d.Month(), d.Day())), nil
66}
67
68// UnmarshalJSON reconstitutes the Date from a JSON string conforming to RFC3339 full-date (i.e.,
69// 2006-01-02).
70func (d *Date) UnmarshalJSON(data []byte) (err error) {
71	d.Time, err = time.Parse(fullDateJSON, string(data))
72	return err
73}
74
75// MarshalText preserves the Date as a byte array conforming to RFC3339 full-date (i.e.,
76// 2006-01-02).
77func (d Date) MarshalText() (text []byte, err error) {
78	return []byte(fmt.Sprintf(dateFormat, d.Year(), d.Month(), d.Day())), nil
79}
80
81// UnmarshalText reconstitutes a Date saved as a byte array conforming to RFC3339 full-date (i.e.,
82// 2006-01-02).
83func (d *Date) UnmarshalText(data []byte) (err error) {
84	d.Time, err = time.Parse(fullDate, string(data))
85	return err
86}
87
88// String returns the Date formatted as an RFC3339 full-date string (i.e., 2006-01-02).
89func (d Date) String() string {
90	return fmt.Sprintf(dateFormat, d.Year(), d.Month(), d.Day())
91}
92
93// ToTime returns a Date as a time.Time
94func (d Date) ToTime() time.Time {
95	return d.Time
96}
97