Skip to content

Commit

Permalink
Implement the RFC 1123 format
Browse files Browse the repository at this point in the history
  • Loading branch information
dkhalanskyjb committed Apr 13, 2023
1 parent 6a5d9f6 commit b4e9839
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 0 deletions.
9 changes: 9 additions & 0 deletions core/common/src/format/ValueBagFormat.kt
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,15 @@ public class ValueBagFormat private constructor(private val actualFormat: Format
appendFormatString("ld<'-'mm'-'dd>('T'|'t')lt<hh':'mm':'ss(|'.'f)>uo<('Z'|'z')|+(HH(|':'mm(|':'ss)))>")
}

public val RFC_1123 : ValueBagFormat = build {
appendDayOfWeek(listOf("Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"))
appendLiteral(", ")
appendDayOfMonth()
appendLiteral(' ')
appendMonthName(listOf("Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"))
appendFormatString(" ld<yyyy> lt<hh':'mm':'ss> uo<'GMT'|+(HHmm)>")
}

internal val Cache = LruCache<String, ValueBagFormat>(16) { fromFormatString(it) }
}

Expand Down
53 changes: 53 additions & 0 deletions core/common/test/format/ValueBagFormatTest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*
* Copyright 2019-2023 JetBrains s.r.o. and contributors.
* Use of this source code is governed by the Apache 2.0 License that can be found in the LICENSE.txt file.
*/

package kotlinx.datetime.test.format

import kotlinx.datetime.*
import kotlinx.datetime.format.*
import kotlin.test.*

class ValueBagFormatTest {
@Test
fun testRfc1123() {
val bags = buildMap<ValueBag, Pair<String, Set<String>>> {
put(valueBag(LocalDate(2008, 6, 3), LocalTime(11, 5, 30), UtcOffset.ZERO), ("Tue, 3 Jun 2008 11:05:30 GMT" to setOf()))
put(valueBag(LocalDate(2008, 6, 30), LocalTime(11, 5, 30), UtcOffset.ZERO), ("Mon, 30 Jun 2008 11:05:30 GMT" to setOf()))
put(valueBag(LocalDate(2008, 6, 3), LocalTime(11, 5, 30), UtcOffset(hours = 2)), ("Tue, 3 Jun 2008 11:05:30 +0200" to setOf()))
put(valueBag(LocalDate(2008, 6, 30), LocalTime(11, 5, 30), UtcOffset(hours = -3)), ("Mon, 30 Jun 2008 11:05:30 -0300" to setOf()))
}
test(ValueBagFormat.RFC_1123, bags)
}

private fun valueBag(
date: LocalDate? = null,
time: LocalTime? = null,
offset: UtcOffset? = null,
zone: TimeZone? = null
) = ValueBag().apply {
date?.let { populateFrom(it) }
time?.let { populateFrom(it) }
offset?.let { populateFrom(it) }
timeZoneId = zone?.id
}

private fun assertValueBagsEqual(a: ValueBag, b: ValueBag, message: String? = null) {
assertEquals(a.toLocaldate(), b.toLocaldate(), message)
assertEquals(a.toLocalTime(), b.toLocalTime(), message)
assertEquals(a.toUtcOffset(), b.toUtcOffset(), message)
assertEquals(a.timeZoneId, b.timeZoneId, message)
}

private fun test(format: ValueBagFormat, strings: Map<ValueBag, Pair<String, Set<String>>>) {
for ((value, stringsForValue) in strings) {
val (canonicalString, otherStrings) = stringsForValue
assertEquals(canonicalString, format.format(value), "formatting $value with $format")
assertValueBagsEqual(value, format.parse(canonicalString), "parsing '$canonicalString' with $format")
for (otherString in otherStrings) {
assertValueBagsEqual(value, format.parse(otherString), "parsing '$otherString' with $format")
}
}
}
}

0 comments on commit b4e9839

Please sign in to comment.