diff options
| -rw-r--r-- | todo.go | 13 | ||||
| -rw-r--r-- | todolist/app.go | 22 | ||||
| -rw-r--r-- | todolist/date_filter.go | 37 | ||||
| -rw-r--r-- | todolist/date_filter_test.go | 5 | ||||
| -rw-r--r-- | todolist/file_store.go | 25 | ||||
| -rw-r--r-- | todolist/filter.go | 20 | ||||
| -rw-r--r-- | todolist/formatter.go | 52 | ||||
| -rw-r--r-- | todolist/parser.go | 24 | ||||
| -rw-r--r-- | todolist/parser_test.go | 9 | ||||
| -rw-r--r-- | todolist/todo_item.go | 17 | ||||
| -rw-r--r-- | todolist/todo_list.go | 14 | ||||
| -rw-r--r-- | todolist/todo_list_test.go | 20 | ||||
| -rw-r--r-- | todolist/todos.json | 2 | ||||
| -rw-r--r-- | todolist/util.go | 17 | ||||
| -rw-r--r-- | vendor/github.com/jinzhu/now/Guardfile | 3 | ||||
| -rw-r--r-- | vendor/github.com/jinzhu/now/README.md | 104 | ||||
| -rw-r--r-- | vendor/github.com/jinzhu/now/main.go | 103 | ||||
| -rw-r--r-- | vendor/github.com/jinzhu/now/now.go | 182 |
18 files changed, 206 insertions, 463 deletions
@@ -81,6 +81,15 @@ func usage() { yellow.Println("\ttodo uc 33") fmt.Println("\tUncompletes a todo with id 33\n") + blueBold.Println("\nPrioritizing") + fmt.Println("Todos have a priority flag, which will make them bold when listed.\n") + yellow.Println("\ttodo p 33") + fmt.Println("\tPrioritizes a todo with id 33\n") + yellow.Println("\ttodo up 33") + fmt.Println("\tUn-prioritizes a todo with id 33\n") + yellow.Println("\ttodo l p") + fmt.Println("\tlist all priority todos\n") + blueBold.Println("\nArchiving") fmt.Println("You can archive todos once they are done, or if you might come back to them.") fmt.Println("By default, todo will only show unarchived todos.\n") @@ -137,6 +146,10 @@ func routeInput(command string, input string) { app.ExpandTodo(input) case "gc": app.GarbageCollect() + case "p", "prioritize": + app.PrioritizeTodo(input) + case "up", "unprioritize": + app.UnprioritizeTodo(input) case "init": app.InitializeRepo() case "web": diff --git a/todolist/app.go b/todolist/app.go index 20a35ef..a9145a1 100644 --- a/todolist/app.go +++ b/todolist/app.go @@ -150,6 +150,28 @@ func (a *App) ListTodos(input string) { formatter.Print() } +func (a *App) PrioritizeTodo(input string) { + a.Load() + id, _ := a.getId(input) + if id == -1 { + return + } + a.TodoList.Prioritize(id) + a.Save() + fmt.Println("Todo prioritized.") +} + +func (a *App) UnprioritizeTodo(input string) { + a.Load() + id, _ := a.getId(input) + if id == -1 { + return + } + a.TodoList.Unprioritize(id) + a.Save() + fmt.Println("Todo un-prioritized.") +} + func (a *App) getId(input string) (int, *Todo) { re, _ := regexp.Compile("\\d+") if re.MatchString(input) { diff --git a/todolist/date_filter.go b/todolist/date_filter.go index 2bf51e2..b56f117 100644 --- a/todolist/date_filter.go +++ b/todolist/date_filter.go @@ -3,8 +3,6 @@ package todolist import ( "regexp" "time" - - "github.com/jinzhu/now" ) type DateFilter struct { @@ -17,38 +15,38 @@ func NewDateFilter(todos []*Todo) *DateFilter { } func (f *DateFilter) FilterDate(input string) []*Todo { - agendaRegex, _ := regexp.Compile(`agenda .*$`) + agendaRegex, _ := regexp.Compile(`agenda.*$`) if agendaRegex.MatchString(input) { - return f.filterAgenda(now.BeginningOfDay()) + return f.filterAgenda(bod(time.Now())) } r, _ := regexp.Compile(`due .*$`) match := r.FindString(input) switch { case match == "due tod" || match == "due today": - return f.filterToday(now.BeginningOfDay()) + return f.filterToday(bod(time.Now())) case match == "due tom" || match == "due tomorrow": - return f.filterTomorrow(now.BeginningOfDay()) + return f.filterTomorrow(bod(time.Now())) case match == "due sun" || match == "due sunday": - return f.filterDay(now.BeginningOfDay(), time.Sunday) + return f.filterDay(bod(time.Now()), time.Sunday) case match == "due mon" || match == "due monday": - return f.filterDay(now.BeginningOfDay(), time.Monday) + return f.filterDay(bod(time.Now()), time.Monday) case match == "due tue" || match == "due tuesday": - return f.filterDay(now.BeginningOfDay(), time.Tuesday) + return f.filterDay(bod(time.Now()), time.Tuesday) case match == "due wed" || match == "due wednesday": - return f.filterDay(now.BeginningOfDay(), time.Wednesday) + return f.filterDay(bod(time.Now()), time.Wednesday) case match == "due thu" || match == "due thursday": - return f.filterDay(now.BeginningOfDay(), time.Thursday) + return f.filterDay(bod(time.Now()), time.Thursday) case match == "due fri" || match == "due friday": - return f.filterDay(now.BeginningOfDay(), time.Friday) + return f.filterDay(bod(time.Now()), time.Friday) case match == "due sat" || match == "due saturday": - return f.filterDay(now.BeginningOfDay(), time.Saturday) + return f.filterDay(bod(time.Now()), time.Saturday) case match == "due this week": - return f.filterThisWeek(now.BeginningOfDay()) + return f.filterThisWeek(bod(time.Now())) case match == "due next week": - return f.filterNextWeek(now.BeginningOfDay()) + return f.filterNextWeek(bod(time.Now())) case match == "overdue": - return f.filterOverdue(now.BeginningOfDay()) + return f.filterOverdue(bod(time.Now())) } return f.Todos } @@ -57,6 +55,9 @@ func (f *DateFilter) filterAgenda(pivot time.Time) []*Todo { var ret []*Todo for _, todo := range f.Todos { + if todo.Due == "" { + continue + } dueTime, _ := time.ParseInLocation("2006-01-02", todo.Due, f.Location) if dueTime.Before(pivot) || todo.Due == pivot.Format("2006-01-02") { ret = append(ret, todo) @@ -102,7 +103,7 @@ func (f *DateFilter) filterTomorrow(pivot time.Time) []*Todo { func (f *DateFilter) filterThisWeek(pivot time.Time) []*Todo { var ret []*Todo - begin := now.New(f.FindSunday(pivot)).BeginningOfDay() + begin := bod(f.FindSunday(pivot)) end := begin.AddDate(0, 0, 7) for _, todo := range f.Todos { @@ -144,7 +145,7 @@ func (f *DateFilter) filterOverdue(pivot time.Time) []*Todo { } func (f *DateFilter) FindSunday(pivot time.Time) time.Time { - switch now.New(pivot).Weekday() { + switch pivot.Weekday() { case time.Sunday: return pivot case time.Monday: diff --git a/todolist/date_filter_test.go b/todolist/date_filter_test.go index 8ee8db5..444b4ac 100644 --- a/todolist/date_filter_test.go +++ b/todolist/date_filter_test.go @@ -4,7 +4,6 @@ import ( "testing" "time" - "github.com/jinzhu/now" "github.com/stretchr/testify/assert" ) @@ -63,7 +62,7 @@ func TestFilterOverdue(t *testing.T) { var todos []*Todo lastWeekTodo := &Todo{Id: 1, Subject: "one", Due: time.Now().AddDate(0, 0, -7).Format("2006-01-02")} - todayTodo := &Todo{Id: 2, Subject: "two", Due: now.BeginningOfDay().Format("2006-01-02")} + todayTodo := &Todo{Id: 2, Subject: "two", Due: bod(time.Now()).Format("2006-01-02")} tomorrowTodo := &Todo{Id: 3, Subject: "three", Due: time.Now().AddDate(0, 0, 1).Format("2006-01-02")} todos = append(todos, lastWeekTodo) @@ -71,7 +70,7 @@ func TestFilterOverdue(t *testing.T) { todos = append(todos, tomorrowTodo) filter := NewDateFilter(todos) - filtered := filter.filterOverdue(now.BeginningOfDay()) + filtered := filter.filterOverdue(bod(time.Now())) assert.Equal(1, len(filtered)) assert.Equal(1, filtered[0].Id) diff --git a/todolist/file_store.go b/todolist/file_store.go index 5413295..4a7f0e0 100644 --- a/todolist/file_store.go +++ b/todolist/file_store.go @@ -5,6 +5,7 @@ import ( "fmt" "io/ioutil" "os" + "os/user" ) type FileStore struct { @@ -13,22 +14,36 @@ type FileStore struct { } func NewFileStore() *FileStore { - return &FileStore{FileLocation: ".todos.json", Loaded: false} + localrepo := ".todos.json" + usr, _ := user.Current() + homerepo := fmt.Sprintf("%s/.todos.json", usr.HomeDir) + _, err1 := os.Stat(localrepo) + _, err2 := os.Stat(homerepo) + + if err1 == nil { + return &FileStore{FileLocation: localrepo, Loaded: false} + } else if err2 == nil { + return &FileStore{FileLocation: homerepo, Loaded: false} + } else { + fmt.Println("No todo file found!") + fmt.Println("You may run 'todo init' to initialize an empty repo in working directory.") + os.Exit(1) + return nil + } } func (f *FileStore) Load() ([]*Todo, error) { data, err := ioutil.ReadFile(f.FileLocation) if err != nil { - fmt.Println("No todo file found!") - fmt.Println("Initialize a new todo repo by running 'todo init'") + fmt.Println("Error reading", f.FileLocation, "by", err) return nil, err - os.Exit(0) + os.Exit(1) } var todos []*Todo jerr := json.Unmarshal(data, &todos) if jerr != nil { - fmt.Println("Error reading json data", jerr) + fmt.Println("Error reading", f.FileLocation, "by", jerr) return nil, jerr os.Exit(1) } diff --git a/todolist/filter.go b/todolist/filter.go index 7705ca5..8c2a7ad 100644 --- a/todolist/filter.go +++ b/todolist/filter.go @@ -12,6 +12,7 @@ func NewFilter(todos []*Todo) *TodoFilter { func (f *TodoFilter) Filter(input string) []*Todo { f.Todos = f.filterArchived(input) + f.Todos = f.filterPrioritized(input) f.Todos = f.filterProjects(input) f.Todos = f.filterContexts(input) f.Todos = NewDateFilter(f.Todos).FilterDate(input) @@ -38,6 +39,15 @@ func (f *TodoFilter) filterArchived(input string) []*Todo { } } +func (f *TodoFilter) filterPrioritized(input string) []*Todo { + r, _ := regexp.Compile(`l p`) + if r.MatchString(input) { + return f.getPrioritized() + } else { + return f.Todos + } +} + func (f *TodoFilter) filterProjects(input string) []*Todo { if !f.isFilteringByProjects(input) { return f.Todos @@ -88,6 +98,16 @@ func (f *TodoFilter) getArchived() []*Todo { return ret } +func (f *TodoFilter) getPrioritized() []*Todo { + var ret []*Todo + for _, todo := range f.Todos { + if todo.IsPriority { + ret = append(ret, todo) + } + } + return ret +} + func (f *TodoFilter) getUnarchived() []*Todo { var ret []*Todo for _, todo := range f.Todos { diff --git a/todolist/formatter.go b/todolist/formatter.go index 43d9b1e..c0f3313 100644 --- a/todolist/formatter.go +++ b/todolist/formatter.go @@ -44,20 +44,28 @@ func (f *Formatter) Print() { } func (f *Formatter) printTodo(todo *Todo) { - yellow := color.New(color.FgYellow).SprintFunc() + yellow := color.New(color.FgYellow) + if todo.IsPriority { + yellow.Add(color.Bold, color.Italic) + } fmt.Fprintf(f.Writer, " %s\t%s\t%s\t%s\t\n", - yellow(strconv.Itoa(todo.Id)), + yellow.SprintFunc()(strconv.Itoa(todo.Id)), f.formatCompleted(todo.Completed), - f.formatDue(todo.Due), - f.formatSubject(todo.Subject)) + f.formatDue(todo.Due, todo.IsPriority), + f.formatSubject(todo.Subject, todo.IsPriority)) } -func (f *Formatter) formatDue(due string) string { - blue := color.New(color.FgBlue).SprintFunc() - red := color.New(color.FgRed).SprintFunc() +func (f *Formatter) formatDue(due string, isPriority bool) string { + blue := color.New(color.FgBlue) + red := color.New(color.FgRed) + + if isPriority { + blue.Add(color.Bold, color.Italic) + red.Add(color.Bold, color.Italic) + } if due == "" { - return blue(" ") + return blue.SprintFunc()(" ") } dueTime, err := time.Parse("2006-01-02", due) @@ -68,13 +76,13 @@ func (f *Formatter) formatDue(due string) string { } if isToday(dueTime) { - return blue("today") + return blue.SprintFunc()("today") } else if isTomorrow(dueTime) { - return blue("tomorrow") + return blue.SprintFunc()("tomorrow") } else if isPastDue(dueTime) { - return red(dueTime.Format("Mon Jan 2")) + return red.SprintFunc()(dueTime.Format("Mon Jan 2")) } else { - return blue(dueTime.Format("Mon Jan 2")) + return blue.SprintFunc()(dueTime.Format("Mon Jan 2")) } } @@ -98,9 +106,17 @@ func isPastDue(t time.Time) bool { return time.Now().After(t) } -func (f *Formatter) formatSubject(subject string) string { - red := color.New(color.FgRed).SprintFunc() - magenta := color.New(color.FgMagenta).SprintFunc() +func (f *Formatter) formatSubject(subject string, isPriority bool) string { + + red := color.New(color.FgRed) + magenta := color.New(color.FgMagenta) + white := color.New(color.FgWhite) + + if isPriority { + red.Add(color.Bold, color.Italic) + magenta.Add(color.Bold, color.Italic) + white.Add(color.Bold, color.Italic) + } splitted := strings.Split(subject, " ") projectRegex, _ := regexp.Compile(`\+[\p{L}\d_]+`) @@ -110,11 +126,11 @@ func (f *Formatter) formatSubject(subject string) string { for _, word := range splitted { if projectRegex.MatchString(word) { - coloredWords = append(coloredWords, magenta(word)) + coloredWords = append(coloredWords, magenta.SprintFunc()(word)) } else if contextRegex.MatchString(word) { - coloredWords = append(coloredWords, red(word)) + coloredWords = append(coloredWords, red.SprintFunc()(word)) } else { - coloredWords = append(coloredWords, word) + coloredWords = append(coloredWords, white.SprintFunc()(word)) } } return strings.Join(coloredWords, " ") diff --git a/todolist/parser.go b/todolist/parser.go index 6cf1967..24a4016 100644 --- a/todolist/parser.go +++ b/todolist/parser.go @@ -7,8 +7,6 @@ import ( "strconv" "strings" "time" - - "github.com/jinzhu/now" ) type Parser struct{} @@ -79,9 +77,9 @@ func (p *Parser) Due(input string, day time.Time) string { case "none": return "" case "today", "tod": - return now.BeginningOfDay().Format("2006-01-02") + return bod(time.Now()).Format("2006-01-02") case "tomorrow", "tom": - return now.BeginningOfDay().AddDate(0, 0, 1).Format("2006-01-02") + return bod(time.Now()).AddDate(0, 0, 1).Format("2006-01-02") case "monday", "mon": return p.monday(day) case "tuesday", "tue": @@ -97,8 +95,8 @@ func (p *Parser) Due(input string, day time.Time) string { case "sunday", "sun": return p.sunday(day) case "next week": - n := now.BeginningOfDay() - return now.New(n).Monday().AddDate(0, 0, 7).Format("2006-01-02") + n := bod(time.Now()) + return getNearestMonday(n).AddDate(0, 0, 7).Format("2006-01-02") } return p.parseArbitraryDate(res, time.Now()) } @@ -137,37 +135,37 @@ func (p *Parser) parseArbitraryDateWithYear(_date string, year int) time.Time { } func (p *Parser) monday(day time.Time) string { - mon := now.New(day).Monday() + mon := getNearestMonday(day) return p.thisOrNextWeek(mon, day) } func (p *Parser) tuesday(day time.Time) string { - tue := now.New(day).Monday().AddDate(0, 0, 1) + tue := getNearestMonday(day).AddDate(0, 0, 1) return p.thisOrNextWeek(tue, day) } func (p *Parser) wednesday(day time.Time) string { - tue := now.New(day).Monday().AddDate(0, 0, 2) + tue := getNearestMonday(day).AddDate(0, 0, 2) return p.thisOrNextWeek(tue, day) } func (p *Parser) thursday(day time.Time) string { - tue := now.New(day).Monday().AddDate(0, 0, 3) + tue := getNearestMonday(day).AddDate(0, 0, 3) return p.thisOrNextWeek(tue, day) } func (p *Parser) friday(day time.Time) string { - tue := now.New(day).Monday().AddDate(0, 0, 4) + tue := getNearestMonday(day).AddDate(0, 0, 4) return p.thisOrNextWeek(tue, day) } func (p *Parser) saturday(day time.Time) string { - tue := now.New(day).Monday().AddDate(0, 0, 5) + tue := getNearestMonday(day).AddDate(0, 0, 5) return p.thisOrNextWeek(tue, day) } func (p *Parser) sunday(day time.Time) string { - tue := now.New(day).Monday().AddDate(0, 0, 6) + tue := getNearestMonday(day).AddDate(0, 0, 6) return p.thisOrNextWeek(tue, day) } diff --git a/todolist/parser_test.go b/todolist/parser_test.go index 791958c..cbb94e8 100644 --- a/todolist/parser_test.go +++ b/todolist/parser_test.go @@ -6,7 +6,6 @@ import ( "testing" "time" - "github.com/jinzhu/now" "github.com/stretchr/testify/assert" ) @@ -75,11 +74,11 @@ func TestParseContexts(t *testing.T) { func TestDueToday(t *testing.T) { parser := &Parser{} todo := parser.ParseNewTodo("do this thing with @bob and @mary due today") - if todo.Due != now.BeginningOfDay().Format("2006-01-02") { + if todo.Due != bod(time.Now()).Format("2006-01-02") { fmt.Println("Date is different", todo.Due, time.Now()) } todo = parser.ParseNewTodo("do this thing with @bob and @mary due tod") - if todo.Due != now.BeginningOfDay().Format("2006-01-02") { + if todo.Due != bod(time.Now()).Format("2006-01-02") { fmt.Println("Date is different", todo.Due, time.Now()) } } @@ -87,11 +86,11 @@ func TestDueToday(t *testing.T) { func TestDueTomorrow(t *testing.T) { parser := &Parser{} todo := parser.ParseNewTodo("do this thing with @bob and @mary due tomorrow") - if todo.Due != now.BeginningOfDay().AddDate(0, 0, 1).Format("2006-01-02") { + if todo.Due != bod(time.Now()).AddDate(0, 0, 1).Format("2006-01-02") { fmt.Println("Date is different", todo.Due, time.Now()) } todo = parser.ParseNewTodo("do this thing with @bob and @mary due tom") - if todo.Due != now.BeginningOfDay().AddDate(0, 0, 1).Format("2006-01-02") { + if todo.Due != bod(time.Now()).AddDate(0, 0, 1).Format("2006-01-02") { fmt.Println("Date is different", todo.Due, time.Now()) } } diff --git a/todolist/todo_item.go b/todolist/todo_item.go index 6b820b1..273df8d 100644 --- a/todolist/todo_item.go +++ b/todolist/todo_item.go @@ -3,17 +3,18 @@ package todolist import "time" type Todo struct { - Id int `json:"id"` - Subject string `json:"subject"` - Projects []string `json:"projects"` - Contexts []string `json:"contexts"` - Due string `json:"due"` - Completed bool `json:"completed"` - Archived bool `json:"archived"` + Id int `json:"id"` + Subject string `json:"subject"` + Projects []string `json:"projects"` + Contexts []string `json:"contexts"` + Due string `json:"due"` + Completed bool `json:"completed"` + Archived bool `json:"archived"` + IsPriority bool `json:"isPriority"` } func NewTodo() *Todo { - return &Todo{Completed: false, Archived: false} + return &Todo{Completed: false, Archived: false, IsPriority: false} } func (t Todo) Valid() bool { diff --git a/todolist/todo_list.go b/todolist/todo_list.go index ea8ecbe..19fe0b7 100644 --- a/todolist/todo_list.go +++ b/todolist/todo_list.go @@ -63,6 +63,20 @@ func (t *TodoList) IndexOf(todoToFind *Todo) int { return -1 } +func (t *TodoList) Prioritize(id int) { + todo := t.FindById(id) + todo.IsPriority = true + t.Delete(id) + t.Data = append(t.Data, todo) +} + +func (t *TodoList) Unprioritize(id int) { + todo := t.FindById(id) + todo.IsPriority = false + t.Delete(id) + t.Data = append(t.Data, todo) +} + type ByDate []*Todo func (a ByDate) Len() int { return len(a) } diff --git a/todolist/todo_list_test.go b/todolist/todo_list_test.go index eb0bc84..eefd99c 100644 --- a/todolist/todo_list_test.go +++ b/todolist/todo_list_test.go @@ -128,3 +128,23 @@ func TestGarbageCollect(t *testing.T) { assert.Equal(1, list.NextId()) assert.Equal(2, list.MaxId()) } + +func TestPrioritizeNotInTodosJson(t *testing.T) { + assert := assert.New(t) + store := &FileStore{FileLocation: "todos.json"} + list := &TodoList{} + todos, _ := store.Load() + list.Load(todos) + assert.Equal(false, list.FindById(2).IsPriority) +} + +func TestPrioritizeTodo(t *testing.T) { + assert := assert.New(t) + list := &TodoList{} + todo := &Todo{Archived: false, Completed: false, Subject: "testing", IsPriority: false} + list.Add(todo) + list.Prioritize(1) + assert.Equal(true, list.FindById(1).IsPriority) + list.Unprioritize(1) + assert.Equal(false, list.FindById(1).IsPriority) +} diff --git a/todolist/todos.json b/todolist/todos.json index 5e44228..bc147d1 100644 --- a/todolist/todos.json +++ b/todolist/todos.json @@ -1 +1 @@ -[{"id":1,"subject":"this is the first subject","projects":["test1"],"contexts":["root"],"due":"2016-04-04","completed":false,"archived":true},{"id":2,"subject":" audit userify for 2FA","projects":["test1"],"contexts":["root","more"],"due":"","completed":true,"archived":false}]
\ No newline at end of file +[{"id":1,"subject":"this is the first subject","projects":["test1"],"contexts":["root"],"due":"2016-04-04","completed":false,"archived":true,"isPriority":false},{"id":2,"subject":" audit userify for 2FA","projects":["test1"],"contexts":["root","more"],"due":"","completed":true,"archived":false,"isPriority":false}]
\ No newline at end of file diff --git a/todolist/util.go b/todolist/util.go index bbed216..72d475f 100644 --- a/todolist/util.go +++ b/todolist/util.go @@ -1,5 +1,7 @@ package todolist +import "time" + func AddIfNotThere(arr []string, items []string) []string { for _, item := range items { there := false @@ -27,3 +29,18 @@ func AddTodoIfNotThere(arr []*Todo, item *Todo) []*Todo { } return arr } + +func bod(t time.Time) time.Time { + year, month, day := t.Date() + return time.Date(year, month, day, 0, 0, 0, 0, t.Location()) +} + +func getNearestMonday(t time.Time) time.Time { + for { + if t.Weekday() != time.Monday { + t = t.AddDate(0, 0, -1) + } else { + return t + } + } +} diff --git a/vendor/github.com/jinzhu/now/Guardfile b/vendor/github.com/jinzhu/now/Guardfile deleted file mode 100644 index 0b860b0..0000000 --- a/vendor/github.com/jinzhu/now/Guardfile +++ /dev/null @@ -1,3 +0,0 @@ -guard 'gotest' do - watch(%r{\.go$}) -end diff --git a/vendor/github.com/jinzhu/now/README.md b/vendor/github.com/jinzhu/now/README.md deleted file mode 100644 index 073c1c6..0000000 --- a/vendor/github.com/jinzhu/now/README.md +++ /dev/null @@ -1,104 +0,0 @@ -## Now - -Now is a time toolkit for golang - -#### Why the project named `Now`? - -```go -now.BeginningOfDay() -``` -`now` is quite readable, aha? - -#### But `now` is so common I can't search the project with my favorite search engine - -* Star it in github [https://github.com/jinzhu/now](https://github.com/jinzhu/now) -* Search it with [http://godoc.org](http://godoc.org) - -## Install - -``` -go get -u github.com/jinzhu/now -``` - -### Usage - -```go -import "github.com/jinzhu/now" - -time.Now() // 2013-11-18 17:51:49.123456789 Mon - -now.BeginningOfMinute() // 2013-11-18 17:51:00 Mon -now.BeginningOfHour() // 2013-11-18 17:00:00 Mon -now.BeginningOfDay() // 2013-11-18 00:00:00 Mon -now.BeginningOfWeek() // 2013-11-17 00:00:00 Sun -now.FirstDayMonday = true // Set Monday as first day, default is Sunday -now.BeginningOfWeek() // 2013-11-18 00:00:00 Mon -now.BeginningOfMonth() // 2013-11-01 00:00:00 Fri -now.BeginningOfQuarter() // 2013-10-01 00:00:00 Tue -now.BeginningOfYear() // 2013-01-01 00:00:00 Tue - -now.EndOfMinute() // 2013-11-18 17:51:59.999999999 Mon -now.EndOfHour() // 2013-11-18 17:59:59.999999999 Mon -now.EndOfDay() // 2013-11-18 23:59:59.999999999 Mon -now.EndOfWeek() // 2013-11-23 23:59:59.999999999 Sat -now.FirstDayMonday = true // Set Monday as first day, default is Sunday -now.EndOfWeek() // 2013-11-24 23:59:59.999999999 Sun -now.EndOfMonth() // 2013-11-30 23:59:59.999999999 Sat -now.EndOfQuarter() // 2013-12-31 23:59:59.999999999 Tue -now.EndOfYear() // 2013-12-31 23:59:59.999999999 Tue - - -// Use another time -t := time.Date(2013, 02, 18, 17, 51, 49, 123456789, time.Now().Location()) -now.New(t).EndOfMonth() // 2013-02-28 23:59:59.999999999 Thu - - -// Don't want be bothered with the First Day setting, Use Monday, Sunday -now.Monday() // 2013-11-18 00:00:00 Mon -now.Sunday() // 2013-11-24 00:00:00 Sun (Next Sunday) -now.EndOfSunday() // 2013-11-24 23:59:59.999999999 Sun (End of next Sunday) - -t := time.Date(2013, 11, 24, 17, 51, 49, 123456789, time.Now().Location()) // 2013-11-24 17:51:49.123456789 Sun -now.New(t).Monday() // 2013-11-18 00:00:00 Sun (Last Monday if today is Sunday) -now.New(t).Sunday() // 2013-11-24 00:00:00 Sun (Beginning Of Today if today is Sunday) -now.New(t).EndOfSunday() // 2013-11-24 23:59:59.999999999 Sun (End of Today if today is Sunday) -``` - -#### Parse String - -```go -time.Now() // 2013-11-18 17:51:49.123456789 Mon - -// Parse(string) (time.Time, error) -t, err := now.Parse("12:20") // 2013-11-18 12:20:00, nil -t, err := now.Parse("1999-12-12 12:20") // 1999-12-12 12:20:00, nil -t, err := now.Parse("99:99") // 2013-11-18 12:20:00, Can't parse string as time: 99:99 - -// MustParse(string) time.Time -now.MustParse("2013-01-13") // 2013-01-13 00:00:00 -now.MustParse("02-17") // 2013-02-17 00:00:00 -now.MustParse("2-17") // 2013-02-17 00:00:00 -now.MustParse("8") // 2013-11-18 08:00:00 -now.MustParse("2002-10-12 22:14") // 2002-10-12 22:14:00 -now.MustParse("99:99") // panic: Can't parse string as time: 99:99 -``` - -Extend `now` to support more formats is quite easy, just update `TimeFormats` variable with `time.Format` like time layout - -```go -now.TimeFormats = append(now.TimeFormats, "02 Jan 2006 15:04") -``` - -Please send me pull requests if you want a format to be supported officially - -# Author - -**jinzhu** - -* <http://github.com/jinzhu> -* <wosmvp@gmail.com> -* <http://twitter.com/zhangjinzhu> - -## License - -Released under the [MIT License](http://www.opensource.org/licenses/MIT). diff --git a/vendor/github.com/jinzhu/now/main.go b/vendor/github.com/jinzhu/now/main.go deleted file mode 100644 index 5210ba2..0000000 --- a/vendor/github.com/jinzhu/now/main.go +++ /dev/null @@ -1,103 +0,0 @@ -// Package now is a time toolkit for golang. -// -// More details README here: https://github.com/jinzhu/now -// -// import "github.com/jinzhu/now" -// -// now.BeginningOfMinute() // 2013-11-18 17:51:00 Mon -// now.BeginningOfDay() // 2013-11-18 00:00:00 Mon -// now.EndOfDay() // 2013-11-18 23:59:59.999999999 Mon -package now - -import "time" - -var FirstDayMonday bool -var TimeFormats = []string{"1/2/2006", "1/2/2006 15:4:5", "2006-1-2 15:4:5", "2006-1-2 15:4", "2006-1-2", "1-2", "15:4:5", "15:4", "15", "15:4:5 Jan 2, 2006 MST"} - -type Now struct { - time.Time -} - -func New(t time.Time) *Now { - return &Now{t} -} - -func BeginningOfMinute() time.Time { - return New(time.Now()).BeginningOfMinute() -} - -func BeginningOfHour() time.Time { - return New(time.Now()).BeginningOfHour() -} - -func BeginningOfDay() time.Time { - return New(time.Now()).BeginningOfDay() -} - -func BeginningOfWeek() time.Time { - return New(time.Now()).BeginningOfWeek() -} - -func BeginningOfMonth() time.Time { - return New(time.Now()).BeginningOfMonth() -} - -func BeginningOfQuarter() time.Time { - return New(time.Now()).BeginningOfQuarter() -} - -func BeginningOfYear() time.Time { - return New(time.Now()).BeginningOfYear() -} - -func EndOfMinute() time.Time { - return New(time.Now()).EndOfMinute() -} - -func EndOfHour() time.Time { - return New(time.Now()).EndOfHour() -} - -func EndOfDay() time.Time { - return New(time.Now()).EndOfDay() -} - -func EndOfWeek() time.Time { - return New(time.Now()).EndOfWeek() -} - -func EndOfMonth() time.Time { - return New(time.Now()).EndOfMonth() -} - -func EndOfQuarter() time.Time { - return New(time.Now()).EndOfQuarter() -} - -func EndOfYear() time.Time { - return New(time.Now()).EndOfYear() -} - -func Monday() time.Time { - return New(time.Now()).Monday() -} - -func Sunday() time.Time { - return New(time.Now()).Sunday() -} - -func EndOfSunday() time.Time { - return New(time.Now()).EndOfSunday() -} - -func Parse(strs ...string) (time.Time, error) { - return New(time.Now()).Parse(strs...) -} - -func MustParse(strs ...string) time.Time { - return New(time.Now()).MustParse(strs...) -} - -func Between(time1, time2 string) bool { - return New(time.Now()).Between(time1, time2) -} diff --git a/vendor/github.com/jinzhu/now/now.go b/vendor/github.com/jinzhu/now/now.go deleted file mode 100644 index 97208d5..0000000 --- a/vendor/github.com/jinzhu/now/now.go +++ /dev/null @@ -1,182 +0,0 @@ -package now - -import ( - "errors" - "regexp" - "time" -) - -func (now *Now) BeginningOfMinute() time.Time { - return now.Truncate(time.Minute) -} - -func (now *Now) BeginningOfHour() time.Time { - return now.Truncate(time.Hour) -} - -func (now *Now) BeginningOfDay() time.Time { - d := time.Duration(-now.Hour()) * time.Hour - return now.BeginningOfHour().Add(d) -} - -func (now *Now) BeginningOfWeek() time.Time { - t := now.BeginningOfDay() - weekday := int(t.Weekday()) - if FirstDayMonday { - if weekday == 0 { - weekday = 7 - } - weekday = weekday - 1 - } - - d := time.Duration(-weekday) * 24 * time.Hour - return t.Add(d) -} - -func (now *Now) BeginningOfMonth() time.Time { - t := now.BeginningOfDay() - d := time.Duration(-int(t.Day())+1) * 24 * time.Hour - return t.Add(d) -} - -func (now *Now) BeginningOfQuarter() time.Time { - month := now.BeginningOfMonth() - offset := (int(month.Month()) - 1) % 3 - return month.AddDate(0, -offset, 0) -} - -func (now *Now) BeginningOfYear() time.Time { - t := now.BeginningOfDay() - d := time.Duration(-int(t.YearDay())+1) * 24 * time.Hour - return t.Truncate(time.Hour).Add(d) -} - -func (now *Now) EndOfMinute() time.Time { - return now.BeginningOfMinute().Add(time.Minute - time.Nanosecond) -} - -func (now *Now) EndOfHour() time.Time { - return now.BeginningOfHour().Add(time.Hour - time.Nanosecond) -} - -func (now *Now) EndOfDay() time.Time { - return now.BeginningOfDay().Add(24*time.Hour - time.Nanosecond) -} - -func (now *Now) EndOfWeek() time.Time { - return now.BeginningOfWeek().AddDate(0, 0, 7).Add(-time.Nanosecond) -} - -func (now *Now) EndOfMonth() time.Time { - return now.BeginningOfMonth().AddDate(0, 1, 0).Add(-time.Nanosecond) -} - -func (now *Now) EndOfQuarter() time.Time { - return now.BeginningOfQuarter().AddDate(0, 3, 0).Add(-time.Nanosecond) -} - -func (now *Now) EndOfYear() time.Time { - return now.BeginningOfYear().AddDate(1, 0, 0).Add(-time.Nanosecond) -} - -func (now *Now) Monday() time.Time { - t := now.BeginningOfDay() - weekday := int(t.Weekday()) - if weekday == 0 { - weekday = 7 - } - d := time.Duration(-weekday+1) * 24 * time.Hour - return t.Truncate(time.Hour).Add(d) -} - -func (now *Now) Sunday() time.Time { - t := now.BeginningOfDay() - weekday := int(t.Weekday()) - if weekday == 0 { - return t - } else { - d := time.Duration(7-weekday) * 24 * time.Hour - return t.Truncate(time.Hour).Add(d) - } -} - -func (now *Now) EndOfSunday() time.Time { - return now.Sunday().Add(24*time.Hour - time.Nanosecond) -} - -func parseWithFormat(str string) (t time.Time, err error) { - for _, format := range TimeFormats { - t, err = time.Parse(format, str) - if err == nil { - return - } - } - err = errors.New("Can't parse string as time: " + str) - return -} - -func (now *Now) Parse(strs ...string) (t time.Time, err error) { - var setCurrentTime bool - parseTime := []int{} - currentTime := []int{now.Second(), now.Minute(), now.Hour(), now.Day(), int(now.Month()), now.Year()} - currentLocation := now.Location() - - for _, str := range strs { - onlyTime := regexp.MustCompile(`^\s*\d+(:\d+)*\s*$`).MatchString(str) // match 15:04:05, 15 - - t, err = parseWithFormat(str) - location := t.Location() - if location.String() == "UTC" { - location = currentLocation - } - - if err == nil { - parseTime = []int{t.Second(), t.Minute(), t.Hour(), t.Day(), int(t.Month()), t.Year()} - onlyTime = onlyTime && (parseTime[3] == 1) && (parseTime[4] == 1) - - for i, v := range parseTime { - // Don't reset hour, minute, second if it is a time only string - if onlyTime && i <= 2 { - continue - } - - // Fill up missed information with current time - if v == 0 { - if setCurrentTime { - parseTime[i] = currentTime[i] - } - } else { - setCurrentTime = true - } - - // Default day and month is 1, fill up it if missing it - if onlyTime { - if i == 3 || i == 4 { - parseTime[i] = currentTime[i] - continue - } - } - } - } - - if len(parseTime) > 0 { - t = time.Date(parseTime[5], time.Month(parseTime[4]), parseTime[3], parseTime[2], parseTime[1], parseTime[0], 0, location) - currentTime = []int{t.Second(), t.Minute(), t.Hour(), t.Day(), int(t.Month()), t.Year()} - } - } - return -} - -func (now *Now) MustParse(strs ...string) (t time.Time) { - t, err := now.Parse(strs...) - if err != nil { - panic(err) - } - return t -} - -func (now *Now) Between(time1, time2 string) bool { - restime := now.MustParse(time1) - restime2 := now.MustParse(time2) - return now.After(restime) && now.Before(restime2) -} |
