App Inventor Clock problem

And this is exactly the reason why I created the extension:

From my extension description:
"Hence this extension (some of it can also be implemented with the on-board methods, but I want to simplify it:)"

Exactly.....
:+1:

If you look at the instants created:

1 Like

Yes, but what is with that?

I don't know. We have done this before :wink:

I just know that once you get down to doing durations of milliseconds that calculation/format adds an hour - sometimes....

Yes, see also the grayed out blocks in my extension description.

To understand this behavior, we have to be rigorous about the definitions of the terms

  • Instant
  • Duration

An Instant is a milestone on the road of time. The road starts in the year 1970.
Some Instants are Milestones in today's section of the road, starting at midnight, depending on where you got them (DatePicker vs TimePicker, etc.)
You can tell you have an Instant when you try to display it as text and you get a lot of labelled details you did not expect.

A Duration is a pure number of milliseconds, usually gotten by a Clock block of that name or by subtracting instances of Clock1.SystemTime.

Now let's examine the OP's blocks ...
2a9f295603396863da313379ed97df4f948d3f14_2_690x122

I circled the fatal assignment. (The Blocks Editor occasionally saves you from linking incompatible blocks, but apparently not here.)

The FormatTime block was asking for an Instant.
You did not give it an Instant.
You gave it a Duration.
I did not check the documentation for the FormatTime block to see how it should respond to such abuse. I would be surprised to see if it has an explicit response to this.

As the old motto goes,
Garbage In
Garbage Out.

P.S. Here is a copy of the Clock docs, for Yandex to translate for you ...

Clock

clock

Non-visible component that provides the instant in time using the internal clock on the phone. It can fire a timer at regularly set intervals and perform time calculations, manipulations, and conversions.

Operations on dates and times, such as from DatePicker and TimePicker , are accomplished through methods in Clock. Date and Time are represented as InstantInTime and Duration.

Instants are assumed to be in the device’s local time zone. When they are converted to or from milliseconds, the milliseconds for a given Instance are calculated from January 1, 1970 in UTC (Greenwich Mean Time).

Methods to convert an Instant to text are also available. Acceptable patterns are empty string, MM/dd/YYYY HH:mm:ss a , or MMM d, yyyy HH:mm . The empty string will provide the default format, which is "MMM d, yyyy HH:mm:ss a" for FormatDateTime , "MMM d, yyyy" for FormatDate . To see all possible formats, please see here.

A note on combining date and time: In order to combine the date from one Instant and the time from another, for example from a DatePicker and TimePicker , extract the parts as text and use the text to create a new Instant. For example:

Properties

TimerAlwaysFires

Will fire even when application is not showing on the screen if true

TimerEnabled

Specifies whether the Timer event should run.

TimerInterval

Specifies the interval between subsequent Timer events.

Note : Drift may occur over time and that the system may not honor the timing specified here if the app or another process on the phone is busy.

Events

Timer()

The Timer event runs when the timer has gone off.

Methods

AddDays( instant , quantity )

Returns an instant in time some days after the given instant.

AddDuration( instant , quantity )

Returns an instant in time some duration after the argument

AddHours( instant , quantity )

Returns an instant in time some hours after the given instant.

AddMinutes( instant , quantity )

Returns an instant in time some minutes after the given instant.

AddMonths( instant , quantity )

Returns an instant in time some months after the given instant.

AddSeconds( instant , quantity )

Returns an instant in time some seconds after the given instant.

AddWeeks( instant , quantity )

Returns An instant in time some weeks after the given instant.

AddYears( instant , quantity )

Returns an instant in time some years after the given instant.

DayOfMonth( instant )

Returns the day of the month.

Duration( start , end )

Returns the milliseconds by which end follows start (+ or -)

DurationToDays( duration )

Returns the duration converted from milliseconds to days.

DurationToHours( duration )

Returns the duration converted from milliseconds to hours.

DurationToMinutes( duration )

Returns the duration converted from milliseconds to minutes.

DurationToSeconds( duration )

Returns the duration converted from milliseconds to seconds.

DurationToWeeks( duration )

Returns the duration converted from milliseconds to weeks.

FormatDate( instant , pattern )

Converts and formats an instant into a string of date with the specified pattern. To learn more about valid patterns, please see SimpleDateFormat.

FormatDateTime( instant , pattern )

Converts and formats an instant into a string of date and time with the specified pattern. To learn more about valid patterns, please see SimpleDateFormat.

FormatTime( instant )

Converts and formats the given instant into a string with the specified pattern. To learn more about valid patterns, please see SimpleDateFormat.

GetMillis( instant )

Returns the instant in time measured as milliseconds since 1970.

Hour( instant )

Returns the hours for the given date.

MakeDate( year , month , day )

Returns an instant in time specified by year, month, date in UTC. Valid values for the month field are 1-12 and 1-31 for the day field.

MakeInstant( from )

Returns an instant in time specified by MM/dd/YYYY hh:mm:ss or MM/dd/YYYY or hh:mm.

MakeInstantFromMillis( millis )

Returns an instant in time specified by the milliseconds since 1970 in UTC.

MakeInstantFromParts( year , month , day , hour , minute , second )

Returns an instant in time specified by year, month, date, hour, minute, second in UTC.

MakeTime( hour , minute , second )

Returns an instant in time specified by hour, minute, second in UTC.

Minute( instant )

Returns the minutes for the given date.

Month( instant )

Returns the number of the month for the given instant.

MonthName( instant )

Returns the name of the month for the given instant.

Now()

Returns the current instant in time read from phone’s clock.

Second( instant )

Returns the seconds for the given instant.

SystemTime()

Returns the phone’s internal time.

Weekday( instant )

Returns the weekday for the given instant.

WeekdayName( instant )

Returns the name of the weekday for the given instant.

Year( instant )

Returns the year of the given instant.

4 Likes

You get the same output:

I neglected to define Milliseconds with a Capital M before, when I defined Instants and Duration. In the Clock component, Milliseconds mean the number of milliseconds of a given Instant after a certain point in 1970. In other words milliseconds is not a Duration, but instead is the expression of an Instant in time by its offset from the zero Instant in 1970.

New let's examine the latest bogus calculation closely:
c629555841b18e8cbce0f73432439f4ce19f3465_2_690x204
Like stomping on a lump under the rug, the type mismatch has moved to a new socket.

All that had been happening so far is not the measurement of a Duration, but instead it has been taking a stab at determination of the hour of the day when the measurement of time started, at 1 AM on a certain day in 1970.

3 Likes

But is shows that format time block just gets the millisecond value from the instant, or accepts a millisecond value

This is what causes the problem:

image

(in my locale....?)

Here's some more experimental evidence ...
Capture

It's not time, it's space!

My MemuPlay emulator was born in China, in a different time zone than your test devices, which likely return different values to these blocks.

The answer was in the Instant expansions from further back in this thread ...
c0b66d0260e84d94009edc181a6baa4560ced335_2_690x378

The zone offset is geographically based.

3 Likes

It's bonkers!! :smiley:

1 Like

Capture

Here's my zone offset, as extra evidence.

2 Likes

So my prior statement about the beginning of time was incomplete.

The question should not have been
"When did time begin?", but instead should be
"When and where did time begin?"

3 Likes

lol @ABG :smiley:

1 Like

Thank you @ABG for these deeper insights and clarifications. :+1:
This should be added to the FAQ.

2 Likes

(added to FAQ)

2 Likes

Certifico los errores de los métodos de AI2 para calcular las diferencias de tiempos en horas, minutos, segundos entre dos fechas (o instantes de tiempos) debido al UTC determinado por la corrección de la zona geográfica del equipo. Lo he solucionado realizando los cálculos internos en lugar de utilizar los métodos que facilita AI2 ya que sus resultados son incorrectos.


A user told me that he had the same problem, that he was getting the wrong time when the sum "crossed" midnight.

With @ABG and @TIMAI2's comments about ZONE_OFFSET, I made this little example.

I get the ZONE_OFFSET and add (or subtract) it to the time.

Note that if you go to Settings and change the Time Zone of your mobile, the ZONE_OFFSET changes, but the calculation remains correct.

p66A_suma_hora.aia (3.6 KB)

https://www.baeldung.com/java-daylight-savings