我有一种方法可以在Java中查看日历,该日历可以按年份,星期几和周数来计算日期。
现在,当我计算2017年的日期时,一切正常。但是,当我计算2018年1月的日期时,需要2017年的日期。
我的代码看起来像
INSERT INTO "orders" ("company_id", "price", "quantity", "order_date", "delivery_date", "created_at", "updated_at", "discount", "order_number", "invoice_number", "type", "dc_number", "user_id", "due_date", "status_value_id") VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15) RETURNING "id" [["company_id", 13], ["price", 11000.0], ["quantity", 10], ["order_date", 2017-11-12 19:00:00 UTC], ["delivery_date", 2017-11-12 19:00:00 UTC], ["created_at", 2017-11-13 06:06:52 UTC], ["updated_at", 2017-11-13 06:06:52 UTC], ["discount", 0.0], ["order_number", 26], ["invoice_number", 26], ["type", "RegisteredOrder"], ["dc_number", "10"], ["user_id", 1], ["due_date", 2017-12-12 19:00:00 UTC], ["status_value_id", 9]]
SQL (16.0ms) INSERT INTO "order_products" ("order_id", "created_at", "updated_at") VALUES ($1, $2, $3) RETURNING "id" [["order_id", 90], ["created_at", 2017-11-13 06:06:52 UTC], ["updated_at", 2017-11-13 06:06:52 UTC]]
结果是2018-01-02,应该是2018-01-01。这怎么可能?
答案 0 :(得分:12)
调用方法的顺序似乎很重要 你通过降序时间粒度(年,星期和星期几)来调用它们,你得到了正确的结果:
long weekNumber = 1;
long dayOfWeek = 1;
int year = 2018;
LocalDate desiredDate = LocalDate.now()
.withYear(year)
.with(IsoFields.WEEK_OF_WEEK_BASED_YEAR, weekNumber)
.with(ChronoField.DAY_OF_WEEK, dayOfWeek );
System.out.println(desiredDate);
2018年1月1日
请注意,问题来源于:
.with(IsoFields.WEEK_OF_WEEK_BASED_YEAR, weekNumber)
根据当前年份设置周数(1 to 53
)
如果您使用LocalDate
更改年份,那么Java .withYear(year)
API无法调整此值,因为周数信息未保存在LocalDate
实例中。
您确实可以在LocalDate
实施中看到LocalDate
个实例仅由3个字段定义:year
,month
和day
。
public final class LocalDate
implements Temporal, TemporalAdjuster, ChronoLocalDate, Serializable {
...
private final int year;
/**
* The month-of-year.
*/
private final short month;
/**
* The day-of-month.
*/
private final short day;
...
}
所以准确地说,重要的是:
在之前调用 .withYear(year)
.with(IsoFields.WEEK_OF_WEEK_BASED_YEAR, weekNumber);
答案 1 :(得分:1)
我想提到的是,LocalDate还有另一个问题(?)。
此代码还会产生错误的结果:
<p>
<strong>Title:</strong>
<%= @article.title %>
</p>
<p>
<strong>Text:</strong>
<%= @article.text %>
</p>
<h2>Comments</h2>
<%= render @article.comments %>
<h2>Add a comment:</h2>
<%= form_with(model: [ @article, @article.comments.build ], local: true) do |form| %>
<p>
<%= form.label :commenter %><br>
<%= form.text_field :commenter %>
</p>
<p>
<%= form.label :body %><br>
<%= form.text_area :body %>
</p>
<p>
<%= form.submit %>
</p>
<% end %>
<%= link_to 'Edit', edit_article_path(@article) %> |
<%= link_to 'Back', articles_path %>
如果将 int jahr = Integer.parseInt(str[0]);
int woche = Integer.parseInt(str[1]);
LocalDate year = LocalDate.of(jahr, 1, 1);
LocalDate week = year.with(IsoFields.WEEK_OF_WEEK_BASED_YEAR, woche);
LocalDate day = week.with(wochentag);
return day;
变量的创建更改为
year
代码返回预期结果。看来构造LocalDate的方式很重要。我猜时区在“ .of()”版本中被省略了。