birthday

package module
v0.0.0-...-27671ed Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 3, 2025 License: BSD-3-Clause Imports: 16 Imported by: 0

README

birthday

A birthday and special day reminder system.

This program is a webserver that reads names and birthdays from a text file and shows upcoming special days for those people. A special day is any of the following:

  • A person's birthday
  • A person turning a multiple of 1000 days old
  • A person turning a multiple of 100 weeks old
  • A person turning a multiple of 100 months old

Format of the text file

The text file is a TSV file (tab delimited file) with two fields per record:

  • Name
  • Date of Birth (MM/dd/yyyy format. Use MM/dd format if you don't know the year a person was born)

A sample text file may look like this:

John Smith	3/25/1967
Bill Shaw	12/07/1973
Katie Long	3/21/2010
Merna Heitcamp	5/17

Although the records in the file can be in any order, I recommend ordering by name to make it easier to make updates to the file.

Building

To build the server, do the following:

  • Download golang
  • In your home directory, create a go/src/github.com/keep94 folder
  • cd to that folder.
  • Then run git clone [email protected]:keep94/birthday.git
  • Run cd birthday
  • Run go install ./... there
  • You will find the executable at $HOME/go/bin/remind

Running the server

Use $HOME/go/bin/remind -file path/to/tsv/file -http ":8283"

This tells the web server to use path/to/tsv/file for the birthdays and to listen on port 8283.

If you point your browser to http://localhost:8283, you will see the upcoming special events. You get redirected to http://localhost:8283/home

You can use $HOME/go/bin/remind -file path/to/tsv/file and the port defaults to 8080.

You can only see the first 100 special events.

The rest of this document assumes the webserver is listening on port 8080.

Special tricks for viewing upcoming special days

By default, you see upcoming reminders for special days from today up to but not including 21 days from now. The reminders for today come first and are in italics.

Want to see if any special days happened yesterday or the day before

Point your browser to http://localhost:8080/home?date=5/1 Where date is the month and day of the current year. If you want to go back to a prior year, you can use http://localhost:8080/home?date=12/28/2023

Want to see special days for one person

Point your browser to http://localhost:8080/home?q=perez&days=365 This shows only people with perez in their name and shows all special days up to but not including 365 days from now.

Want to see only birthdays and no other special days

Point your browser to http://localhost:8080/home?p=y

The p parameter controls what types of special days show up. Special day types are as follows:

Letter Description
y traditional birthday
d 1000 day multiple
w 100 week multiple
m 100 month multiple
h 6 month multiple. Traditional birthdays and half birthdays

If you wanted to see only traditional birthdays and 100 month multiples, you would use p=ym.

Documentation

Overview

Package birthday contains routines for tracking birthdays.

Index

Constants

This section is empty.

Variables

View Source
var (
	// Currently yearly, 100 months, 100 weeks, 1000 days.
	DefaultPeriods = []Period{
		{Years: 1},
		{Months: 100},
		{Weeks: 100},
		{Days: 1000},
	}
)

Functions

func HasYear

func HasYear(t time.Time) bool

HasYear returns true if t has a year. That is t falls on or after 1 Jan 0001

func Parse

func Parse(s string) (parsed time.Time, err error)

Parse converts s to a time in UTC. s must be of form MM/dd/yyyy or MM/dd. If s is of form MM/dd, the year of returned time is 0. s must be a valid date as no normalizing is done. Invalid dates like '08/32/2006' return an error.

func Query

func Query(query string) func(entry Entry) bool

Query returns a function that returns true if the Entry instance passed to it matches query.

func Read

func Read(r io.Reader, consumer consume2.Consumer[Entry]) error

Read reads a birthday file. consumer consumes the Entry instances read.

func ReadFile

func ReadFile(filename string, consumer consume2.Consumer[Entry]) error

ReadFile reads a birthday file. consumer consumes the Entry instances read.

func Remind

func Remind(
	entries []*Entry,
	periods []Period,
	current time.Time) iter.Seq[Milestone]

Remind returns all upcoming Milestones for the specified entries and periods starting at the date specified by current. Remind returns Milestone instances in chronological order.

func RemindPtrs

func RemindPtrs(
	entries []*Entry,
	periods []Period,
	current time.Time) iter.Seq[*Milestone]

RemindPtrs works like Remind except that it returns Milestone pointers.

func ToString

func ToString(t time.Time) string

ToString returns t as MM/dd/yyyy or as just MM/dd if t falls before 1 Jan 0001.

func ToStringWithWeekDay

func ToStringWithWeekDay(t time.Time) string

ToStringWithWeekDay works like ToString but adds weekday. ToStringWithWeekDay returns a string such as 'Mon 01/02/2006'. ToStringWithWeekDay panics if t falls before 1 Jan 0001.

func Today

func Today(clock date_util.Clock) time.Time

Today returns today's date at midnight in UTC.

Types

type Entry

type Entry struct {
	Name     string
	Birthday time.Time
}

Entry represents a single entry in the birthday database

func EntriesSortedByName

func EntriesSortedByName(entries []*Entry) []*Entry

EntriesSortedByName returns entries sorted by name while leaving the original entries slice unchanged.

type Milestone

type Milestone struct {

	// The person having the milestone
	EntryPtr *Entry

	// The date of the milestone day
	Date time.Time

	// The age of the person on this milestone day
	Age Period

	// If true, age is unknown
	AgeUnknown bool
}

Milestone represents a milestone day.

func (*Milestone) AgeString

func (m *Milestone) AgeString() string

AgeString returns the age as a string e.g "57 years"

func (*Milestone) Less

func (m *Milestone) Less(other *Milestone) bool

Less orders Milestones. Less orders first by Date then by Name then by AgeUnknown and finally by Age.

type Period

type Period struct {
	Years  int
	Months int
	Weeks  int
	Days   int

	// If true, Multiply normalizes.
	Normalize bool
}

Period represents a period of time

func (Period) Add

func (p Period) Add(start time.Time, count int) time.Time

Add adds count of this period to start and returns the result.

func (Period) Diff

func (p Period) Diff(end, start time.Time) int

Diff returns the number of this period between end and start rounded down. Diff panics if this period is not valid.

func (Period) Less

func (p Period) Less(other Period) bool

Less orders Periods. Less orders first by Days, then by Weeks, then by Months, and finally by Years.

func (Period) Multiply

func (p Period) Multiply(count int) Period

Multiply returns p * count. If p.Normalize is true, the returned period is normalized. The Normalize field of returned Period is set to false.

func (Period) String

func (p Period) String() string

func (Period) Valid

func (p Period) Valid() bool

Valid returns true if p represents a net positive period.

type Store

type Store interface {
	Read(consumer consume2.Consumer[Entry]) error
}

Interface Store abstracts away reading the birthday file for testability.

type SystemStore

type SystemStore string

SystemStore reads birthday file from given file path.

func (SystemStore) Read

func (s SystemStore) Read(consumer consume2.Consumer[Entry]) error

Read reads the birthday file at path s. consumer consumes the Entry instances read.

Directories

Path Synopsis
cmd
remind command
upcoming command

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL