Задать вопрос

Golang: пакет time. Возможно ли штатным образом проверить дату на корректность?

Доброго дня!

package main

import (
	"fmt"
	"time"
)

func Check(format, date string) bool {
	_, err := time.Parse(format, date)
	if err != nil {
		return false
	}
	return true
}

func main() {
	fmt.Println(Check("02.01.2006", "29.02.2015")) // true
	fmt.Println(Check("02.01.2006", "30.02.2016")) // true
	fmt.Println(Check("02.01.2006", "31.04.2015")) // true
	fmt.Println(Check("02.01.2006", "32.04.2015")) // false
}


Конечно работа с датой и временем довольно-таки не простая вещь, которой должен заниматься язык. Как это делают другие языки... Ладно, что тип Duration пакета time работает максимум с часами... Но, что бы не учитывать 30/31 день в месяце и високосный год...

Я не вижу штатного способа проверить дату на корректность. Дописывать функционал или есть какие-то библиотеки готовые?

Update

Можно было бы сделать так:
var nonLeapYear = []int{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
var leapYear = []int{31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}

func Check(format string, date string) bool {
	t, err := time.Parse(format, date)
	if err != nil {
		return false
	}
	y, m, d := t.Year(), t.Month(), t.Day()
	l := nonLeapYear
	if y%4 == 0 && (y%100 != 0 || y%400 == 0) {
		l = leapYear
	}
	if d > l[m-1] {
		return false
	}
	return true
}


Но на 29-31 февраля или 31 апреля, Go говорит, что t.Month() это Март (3) и Май (5) соответственно.
Так что использовать штатный Parse не дается возможным. А писать такой же свой, не очень то хочется.

Update #2
Сегодня (18.12.15) дали анонс релиза Go 1.6 beta 1. Теперь time.Parse будет нормально работать. Оперативно.
The time package's Parse function has always rejected any day of month larger than 31, such as January 32. In Go 1.6, Parse now also rejects February 29 in non-leap years, February 30, February 31, April 31, June 31, September 31, and November 31.
  • Вопрос задан
  • 3877 просмотров
Подписаться 3 Оценить Комментировать
Решения вопроса 1
mirrr
@mirrr
Программист и просто хороший человек
Проблема (или нет) в том, что голанг распаршивает дату 30.02.2016 как 01.03.2016. И ошибку не выдает. Потому самый простой вариант - сравнить полученную дату с введенной.
package main

import (
	"fmt"
	"time"
)

func Check(format, date string) bool {
	t, err := time.Parse(format, date)
	if err != nil {
		return false
	}
	return t.Format(format) == date
}

func main() {
	fmt.Println(Check("02.01.2006", "29.02.2015")) // false
	fmt.Println(Check("02.01.2006", "30.02.2016")) // false
	fmt.Println(Check("02.01.2006", "31.04.2015")) // false
	fmt.Println(Check("02.01.2006", "32.04.2015")) // false
}
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы