├── .travis.yml ├── LICENSE ├── README.md ├── age.go ├── age_test.go └── go.mod /.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | go: 3 | - 1.1 4 | - 1.2 5 | - release 6 | - tip 7 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014 Alexander Harkness 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | this software and associated documentation files (the "Software"), to deal in 5 | the Software without restriction, including without limitation the rights to 6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 7 | the Software, and to permit persons to whom the Software is furnished to do so, 8 | subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 15 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 16 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 17 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 18 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 19 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Go-Age [![Build Status](https://travis-ci.org/bearbin/go-age.png?branch=master)](https://travis-ci.org/bearbin/go-age) [![GoDoc](https://godoc.org/github.com/bearbin/go-age?status.png)](https://godoc.org/github.com/bearbin/go-age) 2 | ===== 3 | 4 | Go-Age is a little utility library for go that can calculate the age of an entity easily, and work around difficulties like leap years. 5 | -------------------------------------------------------------------------------- /age.go: -------------------------------------------------------------------------------- 1 | // Package age allows for easy calculation of the age of an entity, provided with the date of birth of that entity. 2 | package age 3 | 4 | import "time" 5 | 6 | // AgeAt gets the age of an entity at a certain time. 7 | func AgeAt(birthDate time.Time, now time.Time) int { 8 | // Get the year number change since the player's birth. 9 | years := now.Year() - birthDate.Year() 10 | 11 | // If the date is before the date of birth, then not that many years have elapsed. 12 | birthDay := getAdjustedBirthDay(birthDate, now) 13 | if now.YearDay() < birthDay { 14 | years -= 1 15 | } 16 | 17 | return years 18 | } 19 | 20 | // Age is shorthand for AgeAt(birthDate, time.Now()), and carries the same usage and limitations. 21 | func Age(birthDate time.Time) int { 22 | return AgeAt(birthDate, time.Now()) 23 | } 24 | 25 | // Gets the adjusted date of birth to work around leap year differences. 26 | func getAdjustedBirthDay(birthDate time.Time, now time.Time) int { 27 | birthDay := birthDate.YearDay() 28 | currentDay := now.YearDay() 29 | if isLeap(birthDate) && !isLeap(now) && birthDay >= 60 { 30 | return birthDay - 1 31 | } 32 | if isLeap(now) && !isLeap(birthDate) && currentDay >= 60 { 33 | return birthDay + 1 34 | } 35 | return birthDay 36 | } 37 | 38 | // Works out if a time.Time is in a leap year. 39 | func isLeap(date time.Time) bool { 40 | year := date.Year() 41 | if year%400 == 0 { 42 | return true 43 | } else if year%100 == 0 { 44 | return false 45 | } else if year%4 == 0 { 46 | return true 47 | } 48 | return false 49 | } 50 | -------------------------------------------------------------------------------- /age_test.go: -------------------------------------------------------------------------------- 1 | package age 2 | 3 | import ( 4 | "testing" 5 | "time" 6 | ) 7 | 8 | type AgeTestCandidate struct { 9 | BirthDate time.Time 10 | CheckingTime time.Time 11 | ExpectedAge int 12 | } 13 | 14 | var AgeTestCandidates = []AgeTestCandidate{ 15 | {time.Date(2000, 3, 14, 0, 0, 0, 0, time.UTC), time.Date(2010, 3, 14, 0, 0, 0, 0, time.UTC), 10}, 16 | {time.Date(2001, 3, 14, 0, 0, 0, 0, time.UTC), time.Date(2009, 3, 14, 0, 0, 0, 0, time.UTC), 8}, 17 | {time.Date(2004, 6, 18, 0, 0, 0, 0, time.UTC), time.Date(2005, 5, 12, 0, 0, 0, 0, time.UTC), 0}, 18 | } 19 | 20 | func TestAgeAt(t *testing.T) { 21 | for _, candidate := range AgeTestCandidates { 22 | gotAge := AgeAt(candidate.BirthDate, candidate.CheckingTime) 23 | if gotAge != candidate.ExpectedAge { 24 | t.Error( 25 | "For", candidate.BirthDate, 26 | "Expected", candidate.ExpectedAge, 27 | "Got", gotAge, 28 | ) 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/bearbin/go-age 2 | --------------------------------------------------------------------------------