Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simplify Date.DateTime #74

Closed
danieleggert opened this issue Apr 21, 2020 · 3 comments · Fixed by #191
Closed

Simplify Date.DateTime #74

danieleggert opened this issue Apr 21, 2020 · 3 comments · Fixed by #191
Assignees
Labels
imap For IMAP issues.

Comments

@danieleggert
Copy link
Collaborator

danieleggert commented Apr 21, 2020

Can we change the format of Date.DateTime to be something like

struct DateTime {
    init?(day: Int, month: Int, year: Int, hour: Int, minute: Int, seconds: Int, zone: Int)
    var day: Int { get }
    var month: Int { get }
    var year: Int { get }
    var hour: Int { get }
    var minute: Int { get }
    var seconds: Int { get }
    var zone: Int { get }
}

i.e. flatten it and simplify using the components?

Maybe move it out of Date such that it’s simply DateTime? IIRC this is only used for INTERNALDATE and if so, maybe rename it to InternalDate?

The storage can be way more compact that 7 Int, it can in fact fit into a single 64 bit value.

We used to use this code:

    init?(day: Int, month: Int, year: Int, hour: Int, minute: Int, seconds: Int, zone: Int) {
        guard
            (1...31).contains(day),
            (1...12).contains(month),
            (0...24).contains(hour),
            (0...60).contains(minute),
            (0...60).contains(seconds),
            ((-24 * 60)...(24 * 60)).contains(zone),
            (1...Int(UInt16.max)).contains(year)
            else { return nil }
        let zoneValue = UInt16(abs(zone))
        let zoneIsNegative = (zone < 0) ? 1 as UInt8 : 0

        var rawValue = 0 as UInt64

        func store<A: UnsignedInteger>(_ value: A, _ a: A) {
            rawValue *= UInt64(a + 1)
            rawValue += UInt64(value)
        }

        store(UInt16(year), 1)
        store(UInt8(zoneIsNegative), 2)
        store(UInt16(zoneValue), 24 * 60)
        store(UInt8(seconds), 60)
        store(UInt8(minute), 60)
        store(UInt8(hour), 60)
        store(UInt8(month), 12)
        store(UInt8(day), 31)

        self.rawValue = rawValue
    }

and

        var remainder = rawValue

        func take<A: UnsignedInteger>(_ a: A) -> A {
            let r = remainder % UInt64(a + 1)
            remainder /= UInt64(a + 1)
            return A(r)
        }

        let day: UInt8 = take(31)
        let month: UInt8 = take(12)
        let hour: UInt8 = take(60)
        let minute: UInt8 = take(60)
        let seconds: UInt8 = take(60)
        let zoneValue: UInt16 = take(24 * 60)
        let zoneIsNegative: UInt8 = take(2)
        let year: UInt16 = take(UInt16.max - 1)
        let zoneMinutes = Int(zoneValue) * ((zoneIsNegative == 0) ? 1 : -1)

to convert between the day, month, year, hour, minute, seconds, zone set and a single UInt64 for compact storage. But we could probably use something better / more performant.

@danieleggert danieleggert changed the title Parse INTERNALDATE Simplify Date.DateTime Apr 21, 2020
@Davidde94 Davidde94 added the imap For IMAP issues. label Apr 22, 2020
@Davidde94 Davidde94 self-assigned this Apr 22, 2020
@Davidde94
Copy link
Collaborator

Also used in the MULTIAPPEND extension, so not sure we can rename to InternalDate

@Davidde94
Copy link
Collaborator

@danieleggert just to confirm, when parsing we'd have to parse, e.g., "JUNE" and convert to "6"?

@danieleggert
Copy link
Collaborator Author

danieleggert commented Apr 23, 2020

I’d go for InternalDate since that’s also what you’d use with MULTIAPPEND.

These are not dates meant for UI — hence the name.

Davidde94 pushed a commit that referenced this issue Jun 15, 2020
* Simplify Date.DateTime -> use InternalDate

Fixes #74

* Changes according to feedback from @Davidde94

* Fix code style.

* More cleanup.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
imap For IMAP issues.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants