问题
In my application, the date and time need to be changed frequently when the tester tests the application. Currently, we have to use the system command date-s to change the system time,But this will cause other applications on the server to be affected as well。I want to change the Date() only this application, and I don't want to change the application itself, because there are so many places where new Date is used
回答1:
The java.util.Date
API is very very old. It was replaced by the Calendar
API which is also old and obsolete and bad, and that in turn was replaced by the java.time
API - see how old j.u.Date
is?
At any rate, j.u.Date
just does not allow what you need here. It has no support for custom clocks.
But java.time
DOES.
You can call: Instant.now()
, which is the new API equivalent of new Date()
(j.u.Date is epically badly named. It does not represent dates at all; it represents instants in time). There is a variant call: Instant.now(clock)
. This lets you pick a custom clock.
Arrange for the code to obtain the clock instance to use, for example via Dependency Injection, or have a way to set it, with an unset clock meaning you default to the system clock (Clock.systemUTC()
), but you can implement your own clock instance, which can indeed do exactly what you need: Have test code 'configure' the clock to return whatever dates/times you need for the test, without requiring messing with your computer's clock at all.
So, your 3-step solution:
Eliminate all usage of the old API:
java.text.DateTimeFormat
,java.util.Date
,java.sql.Timestamp
, these all need to go away. Usejava.time.Instant
,java.time.LocalDateTime
,java.time.LocalDate
,java.time.ZonedDateTime
, etc instead (the new API has way more types, because time is inherently more complicated thanj.u.Date
thinks it is; it is one of the many flaws of that old API. Also eliminate ALL calls toSystem.currentTimeMillis()
as well. Anything that gets 'the current time' in terms of obsolete API needs to go.Set up a dependency injection solution of some sort (write it yourself, or use off the shelf solutions like dagger, guice, spring, etc) so you can inject an instance of Clock. Use the
Instant.now(clock)
form to obtain the 'current' date and time, and never the args-lessInstant.now()
.Implement a custom impl of clock and use this to set all the various points in your code that query 'current date/time' to inject this 'test clock'.
Then, voila. Test valhalla.
来源:https://stackoverflow.com/questions/61470651/how-to-change-the-value-new-date-in-java