GregorianCalendar提供错误的日期编号

时间:2018-03-10 19:10:50

标签: java date kotlin java.util.calendar

我在下面的代码中,我在尝试发布销售订单交易时,包含日期和数量,一旦我在交易日期的{1},getting,它落后31天,显然12月1日被认为是他一年中的第1天!我的代码有什么问题,或者我该如何解决?!

import java.time.LocalDate
import java.time.format.DateTimeFormatter
import java.util.*

data class transaction (var date: LocalDate, var quantity: Double) {

    private var calendar: Calendar = 
            GregorianCalendar(date.year, date.monthValue, date.dayOfMonth)
    var day: Int
        get() = calendar.get(Calendar.DAY_OF_YEAR)
        set(value) = TODO()
}

val formatter: DateTimeFormatter
    get() = DateTimeFormatter.ofPattern("dd.MM.yyyy", Locale.ENGLISH)

fun main(args: Array<String>) {
    var salesOrders = ArrayList<transaction>()
    salesOrders.add(transaction(LocalDate.parse("01.01.2018", formatter), 5.0))

    println(salesOrders[0].date.dayOfMonth) // prints: 1
    println(salesOrders[0].date.monthValue) // prints: 1
    println(salesOrders[0].date.year)       // prints: 2018
    println(salesOrders[0].day)             // prints 32 ??!!
}

2 个答案:

答案 0 :(得分:3)

我建议您完全停止使用CalendarGregorianCalendar

    println(salesOrders[0].date.dayOfYear)  // prints 1

我没有Kotlin,所以我没有测试过。如果您无法解决拼写错误,请在评论中跟进。

CalendarGregorianCalendar已经过时了,LocalDate所属的现代Java日期和时间API可以更好地使用。并提供您希望的所有功能。

我从您的评论中了解到,您需要多年来每天的唯一标识符。您一直在使用calendar.timeInMillis。首先,这是一个糟糕的标识符,因为它随时区变化。相反,我建议使用LocalDate本身或从date.toString获得的字符串表示。如果您需要数字标识符(就像您从calendar.timeInMillis获得的那样),则可以使用date.toEpochDay。这是自1970年1月1日纪元以来的天数,因此每天都是独一无二的(并且不受时区影响)。

答案 1 :(得分:0)

LocalDate.monthValue位于1..12范围内,而Calendar.JANUARY0因此Calendar月位于范围0..11

所以下面的代码应该可以工作:

private var calendar: Calendar = 
            GregorianCalendar(date.year, date.monthValue - 1, date.dayOfMonth)