我想在今天前10天获得,并将时间设置为午夜12点
我已经发现一天有24小时,所以10天会有240小时,所以我有
Calendar cal = Calendar.getInstance();
cal.set(Calendar.HOUR, cal.get(Calendar.HOUR) - 240);
上述方法有效但现在我想将时间设置为12:00
我试过了
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
在上述10天之后添加上述内容现在重置为今天。
可能出现什么问题?
答案 0 :(得分:1)
如果您使用的是java.time库,则可以更轻松,您可以使用:
LocalDateTime date = LocalDateTime.of(
LocalDate.now().minusDays(10),
LocalTime.of(12, 0)
);
例如:
现在是:
2018-04-01T13:30
在10天之前,12点返回:
2018-03-22T12:00
答案 1 :(得分:1)
您使用https://docs.oracle.com/javase/7/docs/api/java/util/Calendar.html,方法set
有此行为
set(f,value)将日历字段f更改为值。另外,它设定 内部成员变量,表示日历字段f已经过 改变。虽然日历字段f立即更改,但是 日历的时间值(以毫秒为单位)不会重新计算,直到下一个 调用get(),getTime(),getTimeInMillis(),add()或roll()。 因此,对set()的多次调用不会触发多次,不必要的 计算。使用set()更改日历字段的结果, 其他日历字段也可能会更改,具体取决于日历 字段,日历字段值和日历系统。此外, get(f)不一定返回通过调用set设置的值 重新计算日历字段后的方法。具体细节 由具体日历类确定。
示例:考虑最初设置为8月31日的GregorianCalendar, 调用集(Calendar.MONTH,Calendar.SEPTEMBER)将日期设置为1999年9月31日。这是一个临时内部表示形式 如果随后调用getTime(),则解析为1999年10月1日。但是,一个 在调用getTime()之前调用set(Calendar.DAY_OF_MONTH,30) 将日期设置为1999年9月30日,因为没有重新计算 在set()之后。
您拨打set
三次,结果是最后add
次。因此,为了您的目的,您需要在{with} set
之后使用方法{{1}}。
答案 2 :(得分:1)
ZonedDateTime.now( // Capture the current moment as seen through the wall-clock time used by the people of a certain region (a time zone).
ZoneId.of( "Pacific/Auckland" ) // Specify a time zone using proper name, `continent/region`, never 3-4 pseudo-codes such as `PST`, `EST`, `IST`.
)
.minusDays( 10 ) // Go back in time ten days, adjusting for time-of-day as need be.
.toLocalDate() // Extract a date-only value.
.atStartOfDay( // Determine the first moment of that date in a certain time zone. Not always 00:00:00.
ZoneId.of( "Pacific/Auckland" )
)
.toString() // Generate a String in standard ISO 8601 format.
2018-03-23T00:00 + 13:00 [太平洋/奥克兰]
您正在使用 java.time 类在几年前取代的麻烦的旧日期时间类。
而不是Calendar
,使用ZonedDateTime
代表某个地区(时区)的人使用的挂钟时间在时间轴上的时刻。
时区对于确定日期至关重要。对于任何给定的时刻,日期在全球范围内因地区而异。例如,在Paris France午夜后的几分钟是新的一天,而Montréal Québec中仍然是“昨天”。
如果未指定时区,则JVM会隐式应用其当前的默认时区。该默认值可能随时更改,因此您的结果可能会有所不同。最好明确指定您期望/预期的时区作为参数。
以continent/region
的格式指定proper time zone name,例如America/Montreal
,Africa/Casablanca
或Pacific/Auckland
。切勿使用诸如EST
或IST
之类的3-4字母缩写,因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!)。
ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
ZonedDateTime zdt = ZonedDateTime.now( z ) ; // Capture the current moment.
如果要使用JVM的当前默认时区,请求它并作为参数传递。如果省略,则隐式应用JVM的当前默认值。最好是明确的,因为默认情况下可以在运行时期间由JVM中任何应用程序的任何线程中的任何代码随时更改。
ZoneId z = ZoneId.systemDefault() ; // Get JVM’s current default time zone.
ZonedDateTime zdt = ZonedDateTime.now( z ) ; // Capture the current moment.
使用Period
指定未附加到年 - 月 - 日时间轴的时间跨度。
Period p = Period.ofDays( 10 ) ;
回到过去。夏令时(DST)等异常会自动处理,并根据需要调整时间。
ZonedDateTime zdtTenDaysAgo = zdt.minus( p ) ;
“午夜”是一个诡计多端的概念,含糊不清。相反,专注于“一天中的第一时刻”的想法。
始终让 java.time 确定第一时刻。不要假设这一天从00:00:00开始。 DST等异常意味着这一天可能会在另一个时间开始,例如01:00:00。要获得第一个时刻,请提取仅日期LocalDate
对象。指定时区以确定该日期何时开始。
LocalDate ldTenDaysAgo = zdtTenDaysAgo.toLocalDate() ;
ZonedDateTime zdtTenDaysAgoStartOfDay = ldTenDaysAgo.atStartOfDay( z ) ;
如果您想查看与UTC相同的时刻,请提取Instant
。
Instant instant = zdtTenDaysAgoStartOfDay.toInstant() ;
java.time框架内置于Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.Date
,Calendar
和& SimpleDateFormat
现在位于Joda-Time的maintenance mode项目建议迁移到java.time类。
要了解详情,请参阅Oracle Tutorial。并搜索Stack Overflow以获取许多示例和解释。规范是JSR 310。
您可以直接与数据库交换 java.time 对象。使用符合JDBC driver或更高版本的JDBC 4.2。不需要字符串,不需要java.sql.*
类。
从哪里获取java.time类?
ThreeTen-Extra项目使用其他类扩展java.time。该项目是未来可能添加到java.time的试验场。您可以在此处找到一些有用的课程,例如Interval
,YearWeek
,YearQuarter
和more。
答案 3 :(得分:0)
要添加或减去,您应该使用static void Main(string[] args)
{
var arr1 = new[] { "000", "110" };
var arr2 = new[] { "111", "011", "000" };
var arr3 = new[] { "101", "000" };
var result = IsAllHaveMoreThen1SequnceDuplicate(new List<string[]> {arr1, arr2, arr3});
}
private static bool IsAllHaveMoreThen1SequnceDuplicate(List<string[]> arrays)
{
if (arrays == null || arrays.Count == 0)
{
return false;
}
var firstArray = arrays[0];
for (var i = 1; i < arrays.Count; i++)
{
var isHaveMoreThen1SequnceDuplicate = IsHaveMoreThen1SequnceDuplicate(firstArray, arrays[i]);
if (!isHaveMoreThen1SequnceDuplicate)
{
return false;
}
}
return true;
}
private static bool IsHaveMoreThen1SequnceDuplicate(string[] arr1, string[] arr2)
{
var globalCounter = 0;
foreach (var s1 in arr1)
{
foreach (var s2 in arr2)
{
var isSameSequence = IsSameSequence(s1, s2);
if (isSameSequence)
{
globalCounter++;
break;
}
}
if (globalCounter == 2)
{
return true;
}
}
return false;
}
private static bool IsSameSequence(string s1, string s2)
{
if (s1 == s2)
{
return true;
}
if (s1.Length != s2.Length)
{
return false;
}
var flags = new int[9];
for (int i = 0; i < s1.Length; i++)
{
var cInt = int.Parse(s1[i].ToString());
flags[cInt]++;
}
for (int i = 0; i < s2.Length; i++)
{
var cInt = int.Parse(s2[i].ToString());
flags[cInt]--;
}
return flags.All(f => f == 0);
}
方法:
add
但要注意这一点,因为由于夏令时效应,一天并不总是与24小时相同:https://www.timeanddate.com/time/dst/transition.html
无论如何,Calendar是一个非常错误的类,最好使用java.time类(API级别26),如果java.time不可用则使用threetenbp:http://www.threeten.org/threetenbp/
请在此处查看如何在Android中进行配置:How to use ThreeTenABP in Android Project
要考虑DST效果,请使用ZonedDateTime:
cal.add(Calendar.HOUR, -240);
这将处理DST的复杂细节,包括DST在午夜开始而实际从凌晨1点开始的情况 - 时间会自动调整。
目前尚不清楚您是否需要午夜(00:00)或中午(12:00)。无论如何,如果你想要中午,只需使用// current date/time
ZonedDateTime.now()
// minus 10 days
.minusDays(10)
// set time to midnight
.with(LocalTime.MIDNIGHT);
。