aboutsummaryrefslogtreecommitdiff
path: root/src/time.odin
diff options
context:
space:
mode:
Diffstat (limited to 'src/time.odin')
-rw-r--r--src/time.odin310
1 files changed, 310 insertions, 0 deletions
diff --git a/src/time.odin b/src/time.odin
new file mode 100644
index 0000000..d6f6046
--- /dev/null
+++ b/src/time.odin
@@ -0,0 +1,310 @@
+package main
+
+import math "core:math"
+import "core:fmt"
+import "core:strings"
+import "core:strconv"
+import "core:slice"
+
+//
+// --- STRUCTURES ---
+//
+
+Weekday : enum{
+ Monday,
+ Tuesday,
+ Wednesday,
+ Thursday,
+ Friday,
+ Saturday,
+ Sunday
+}
+
+Delta :: struct {
+ minutes : int,
+ hours : int,
+ days : int,
+}
+
+Moment :: struct {
+ minutes : int,
+ hours : int,
+ day : int,
+ month : int,
+ year : int,
+}
+
+Timeblock :: struct {
+ start : Moment,
+ end : Moment,
+ valuefactor : f32,
+ price_reason : string,
+}
+
+Workday :: struct {
+ call : Moment,
+ wrap : Moment,
+ planned_wrap : Moment,
+
+ blocks : [15]Timeblock,
+ total_timeblocks : int,
+}
+
+//
+// --- BASIC OPERATIONS ---
+//
+
+windIndividual :: proc(input_moment: ^Moment,
+ minutes: int,
+ hours: int,
+ days: int) {
+
+ // Adding minutes
+ input_moment.minutes += minutes
+ for input_moment.minutes > 59 {
+ input_moment.minutes -= 60
+ input_moment.hours += 1
+ }
+ for input_moment.minutes < 0 {
+ input_moment.minutes += 60
+ input_moment.hours -= 1
+ }
+
+ // Adding hours
+ input_moment.hours += hours
+ for input_moment.hours > 23 {
+ input_moment.hours -= 24
+ input_moment.day += 1
+ }
+ for input_moment.hours < 0 {
+ input_moment.hours += 24
+ input_moment.day -= 1
+ }
+
+ // Adding days
+ input_moment.day += days
+ current_month_length: int = days_in(input_moment.month, input_moment.year)
+
+ for input_moment.day > current_month_length {
+ input_moment.day -= current_month_length
+ input_moment.month += 1
+ if input_moment.month > 12 {
+ input_moment.month -= 12
+ input_moment.year += 1
+ }
+ current_month_length = days_in(input_moment.month, input_moment.year)
+ }
+
+ for input_moment.day < 1 {
+ input_moment.month -= 1
+ if input_moment.month < 1 {
+ input_moment.month += 12
+ input_moment.year -= 1
+ }
+ current_month_length = days_in(input_moment.month, input_moment.year)
+ input_moment.day += current_month_length
+ }
+
+ return
+}
+windDelta :: proc(moment: ^Moment, delta: Delta) {
+ using delta
+ wind(moment, minutes, hours, days)
+ return
+}
+wind :: proc{windIndividual, windDelta}
+
+
+add :: proc(moment: Moment, delta: Delta) -> (output: Moment) {
+ output = moment
+ wind(&output, delta)
+ return
+}
+sub :: proc(moment: Moment, delta: Delta) -> (output: Moment) {
+ output = moment
+ using delta
+ wind(&output, minutes*-1, hours*-1, days*-1)
+ return
+}
+
+gtMoment :: proc(moment_a: Moment, moment_b: Moment) -> bool {
+ // TODO: This is wrong
+ return true
+}
+gtDelta :: proc(delta_a: Delta, delta_b: Delta) -> bool {
+ // TODO: This is wrong
+ return true
+}
+gt :: proc{gtMoment, gtDelta}
+
+diff :: proc(moment_a: Moment, moment_b: Moment) -> (acc: Delta) {
+
+ acc = {0, 0, 0}
+ if moment_a == moment_b do return
+
+ // Uses what I call an accumulator-decumulator design
+ // Count how long it takes to approach a benchmark,
+ // and that count is the difference
+
+ reverse: bool = gt(moment_b, moment_a)
+
+
+ // TODO: Finish writing this
+
+
+ return
+}
+
+sortableTimeDelta :: proc(delta: Delta) -> int {
+ using delta
+ return strconv.atoi(fmt.tprintf("%2i%2i%2i", days, hours, minutes))
+}
+sortableTimeMoment :: proc(moment: Moment) -> int {
+ using moment
+ return strconv.atoi(fmt.tprintf("%4i%2i%2i%2i%2i", year, month, day, hours, minutes))
+}
+
+deltaToString :: proc(delta: Delta) -> (output: string) {
+ using delta
+
+ if hours == 0 &&
+ days == 0 &&
+ minutes == 0 {
+ return "None"
+ }
+
+ cat_array : [dynamic]string
+ printed_prev : bool = false
+
+ if days>0 {
+ buf: [5]byte
+ append(&cat_array, fmt.tprint(days))
+ if days < 2 {
+ append(&cat_array, " day")
+ } else {
+ append(&cat_array, " days")
+ }
+ printed_prev = true
+ }
+
+ if hours>0 {
+
+ if printed_prev do append(&cat_array, ", ")
+
+ buf: [5]byte
+ append(&cat_array, fmt.tprint(hours))
+ if hours < 2 {
+ append(&cat_array, " hour")
+ } else {
+ append(&cat_array, " hours")
+ }
+ printed_prev = true
+ }
+
+ if minutes>0 {
+
+ if printed_prev do append(&cat_array, ", ")
+
+ buf: [5]byte
+ append(&cat_array, fmt.tprint(minutes))
+ if minutes < 2 {
+ append(&cat_array, " minute")
+ } else {
+ append(&cat_array, " minutes")
+ }
+ }
+
+ output = strings.concatenate(cat_array[:])
+ return
+
+}
+
+
+momentToString :: proc(moment: Moment) -> (output: string) {
+ using moment
+
+ cat_array: [dynamic]string
+
+ output = fmt.tprintf("%i-%2i-%2i %2i:%2i", year, month, day, hours, minutes)
+
+ return
+}
+timeblockToString :: proc(block: Timeblock) -> (output: string) {
+ using block
+ s: [3]string = {toString(start), " -> ", toString(end)}
+ output = strings.concatenate(s[:])
+ return
+}
+toString :: proc{deltaToString, momentToString, timeblockToString}
+
+
+
+clockprintMoment :: proc(moment: Moment) -> string {
+ using moment
+ return fmt.tprintf("%2i:%2i", hours, minutes)
+}
+clockprintTimeblock :: proc(block: Timeblock) -> string {
+ using block
+ return fmt.tprintf("%s -> %s", timeprint(start), timeprint(end))
+}
+timeprint :: proc{clockprintTimeblock, clockprintMoment}
+
+
+//
+// --- PROCEDURES ---
+//
+
+days_in :: proc(month: int, year: int) -> int {
+ switch month {
+ case 1:
+ return 31;
+ case 2:
+ if (((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0)){
+ return 29;
+ }
+ return 28;
+ case 3:
+ return 31;
+ case 4:
+ return 30;
+ case 5:
+ return 31;
+ case 6:
+ return 30;
+ case 7:
+ return 31;
+ case 8:
+ return 31;
+ case 9:
+ return 30;
+ case 10:
+ return 31;
+ case 11:
+ return 30;
+ case 12:
+ return 31;
+ }
+ fmt.printf("You just found month nr: %i. Something is very wrong.\n", month)
+ assert(month < 13 && month > 0)
+ return 30
+}
+
+new_workday :: proc(previous_wrap : Moment,
+ calltime : Moment,
+ wraptime : Moment,
+ planned_wraptime : Moment) -> (workday: Workday) {
+
+ workday.call = calltime
+ workday.wrap = wraptime
+ workday.planned_wrap = planned_wraptime
+
+ /*
+ initial_block: Timeblock = {
+ math.max(
+ math.clamp(),
+ )
+ }
+ */
+
+ return
+}