Skip to content

SourceGitea - Timezone support for commits date #416

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed

SourceGitea - Timezone support for commits date #416

wants to merge 1 commit into from

Conversation

pfrancois-ACX
Copy link

@pfrancois-ACX pfrancois-ACX commented Nov 26, 2024

Gitea API response send date in ISO8601 format with timezone informations (Z, UTC+1, UTC-2, ...).

SourceGitea don't take account of the date format and considers that commits date coming from Gitea API response are in UTC timezone leading to timezone offset in bug view page :
exemple

This pull request fix this behavior by adjusting the commit date received from Gitea API response to UTC timezone.

Best regards,

Philippe

@pfrancois-ACX pfrancois-ACX changed the title Timezone support for commits date SourceGitea - Timezone support for commits date Nov 26, 2024
Copy link
Member

@dregad dregad left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for your contribution @pfrancois-ACX.

I don't use Gitea and do not have an example of the actual JSON data you get from the API for the screenshot so I may be wrong as I can't test end-to-end, but it seems to me that if indeed you're always receiving the date in ISO-8601 format (with either Z suffix or +/-offset) then you should be able to simply do

$dt = DateTimeImmutable::createFromFormat( DateTimeInterface::ATOM, $p_json->commit->author->date );
$utc_commit_date =$d->setTimeZone( new DateTimeZone( 'UTC' ) )->format( 'c' );

In any case, the logic you added to process the commit date has several issues IMO

  • timezone offsets are not necessarily full hours (e.g. Iran, India, Nepal...), so $offset_time * 3600 is incorrect
  • PHP's DateTime::ISO8601 format is actually not compatible with ISO-8601; you probably want DateTimeInterface::ATOM.
  • Using a mix of strtotime() and date() calls to adjust for timezone offset feels wrong.

Thinking about it, I'm wondering if in fact the problem's root cause is not in SourceChangeSet::__construct(), which forces UTC timezone when converting the date-time string to a DateTimeImmutable (introduced in #317).

@dregad
Copy link
Member

dregad commented Jan 17, 2025

@pfrancois-ACX are you planning to address the code review comments ?

@pfrancois-ACX
Copy link
Author

Hello @dregad,

Sorry for the delay in my response, end/start of the year are always very busy.

Thanks for your insight regarding my resolution method that wasn't very elegant. I didn't know for the first two point (which show lack in pratice and timzone management). For the third and last point, it's true it is clumsy.
I will give some try to your suggestion and keep you informed of the result.

Regarding your last thought, I'm not sure what's the best method to resolve this issue but, for information, we also have a SVN server and it doesn't present this timzone offset in bug view page (cf. below).
ExempleSVN

So it must take into account somewhere the fact that the constructor force UTC (it is probably the same for all the others source code managers plugins). That's why I tried to resolve this issue with change in the Gitea plugin.

Finally, you can find below a sample of Gitea API response for commit->author->date (in ISO8601 with date in UTC+2).
giteaApi-dateFormat

Best regards,

Philippe

@dregad
Copy link
Member

dregad commented Jan 20, 2025

Merci Philippe

sample of Gitea API response for commit->author->date (in ISO8601 with date in UTC+2).
"2024-09-19T16:14:33+02:00"

In that case, I believe my earlier suggestion should give the expected result, but I'm also surprised because it's a standard format that the DateTimeImmutable constructor called by SourceChangeSet::__construct() should handle natively without the need for pre-conversion, so maybe the bug is elsewhere...

php > print_r( new DateTimeImmutable( "2024-09-19T16:14:33+02:00", new DateTimeZone('UTC') ) );
DateTimeImmutable Object
(
    [date] => 2024-09-19 16:14:33.000000
    [timezone_type] => 1
    [timezone] => +02:00
)

note that the UTC timezone is ignored since +02:00 was part of the original string...

Can you provide the Gitea output for commit 3ba2ee1814 illustrated in your original screenshot ?
Also, what is the value of mantis_plugin_Source_changeset_table.timestamp column for the same ?

we also have a SVN server and it doesn't present this timzone offset in bug view page

Can you check the output of svn log --xml -r6565 (sorry if the syntax is wrong, I have not used SVN for years) ? Maybe it's already in UTC.

I wait for your feedback.

@pfrancois-ACX
Copy link
Author

Hello @dregad,

I think I might have an idea of what's hapenning.

The constructor of SourceChangeSet class receive the commit timestamp and a new DateTimeImmutable object is created with it. Later, in the save function of the class (line 957), this new object is formated without taking into account the timezone specified for compatibility with MySQL < 8.0.19.

# Commit timestamp: can't use DATE_ATOM format to insert datetime,
# as MySQL < 8.0.19 does not support specifying timezone
# @see https://dev.mysql.com/doc/refman/8.0/en/datetime.html
$t_timestamp = $this->timestamp->format( 'Y-m-d H:i:s' );

As the timestamp received from Gitea is in UTC+2, it is this timezone that is saved in database and later, in bug view page, the database timestamp is displayed in the user timezone which lead to the observed offset.

/**
 * Get the changeset's timestamp in the user's timezone.
 *
 * @param string $p_format Date format, defaults to $g_normal_date_format.
 *
 * @return string
 */
public function getLocalTimestamp( $p_format = null )
{
	if( !$p_format ) {
		$p_format = config_get( 'normal_date_format' );
	}

	return date( $p_format, $this->timestamp->getTimestamp() );
}

Below some picture to illustrate this and also the one asked :

  1. The Gitea API response for commit 3ba2ee1814.
    giteaApi-3ba2ee

  2. The changeset database entry from standard Gitea plugin for commit 3ba2ee1814 (saved in UTC+2 timezone).
    gitea-changeset-3ba2ee-impacted

  3. The changeset database entry from patched (with your suggestion) Gitea plugin for commit 3ba2ee1814 (saved in UTC timezone this time).
    gitea-changeset-3ba2ee-notImpacted

  4. The result of the svn log command for the revision 6565 which is indeed in UTC timezone.
    svnLog-xml-r6565

  5. Finally, the changeset database entry for SVN revision 6565 (saved in UTC timezone).
    svn-changeset-r6565

Best regards,

Philippe

@dregad
Copy link
Member

dregad commented Jan 21, 2025

The constructor of SourceChangeSet class receive the commit timestamp and a new DateTimeImmutable object is created with it. Later, in the save function of the class (line 957), this new object is formated without taking into account the timezone specified for compatibility with MySQL < 8.0.19.

# Commit timestamp: can't use DATE_ATOM format to insert datetime,
# as MySQL < 8.0.19 does not support specifying timezone
# @see https://dev.mysql.com/doc/refman/8.0/en/datetime.html
$t_timestamp = $this->timestamp->format( 'Y-m-d H:i:s' );

As the timestamp received from Gitea is in UTC+2, it is this timezone that is saved in database and later, in bug view page, the database timestamp is displayed in the user timezone which lead to the observed offset.

Right, looks like an oversight, I failed to consider that the timestamp would be stored in the original timezone. We need to always store the date in UTC for consistency.

I'm not sure whether it's best for this conversion to occur in the constructor, or in the save() method, but I guess the latter probably makes more sense since this is where the workaround for older MySQL version is.

Could you try with the following patch

diff --git a/Source/Source.API.php b/Source/Source.API.php
index 9b8ba6e..c50ccda 100644
--- a/Source/Source.API.php
+++ b/Source/Source.API.php
@@ -954,7 +954,10 @@ class SourceChangeset {
                # Commit timestamp: can't use DATE_ATOM format to insert datetime,
                # as MySQL < 8.0.19 does not support specifying timezone
                # @see https://dev.mysql.com/doc/refman/8.0/en/datetime.html
-               $t_timestamp = $this->timestamp->format( 'Y-m-d H:i:s' );
+               # so we convert the timestamp to UTC first.
+               $t_timestamp = $this->timestamp
+                       ->setTimezone( new DateTimeZone( 'UTC' ) )
+                       ->format( 'Y-m-d H:i:s' );

                if ( 0 == $this->id ) { # create
                        $t_query = "INSERT INTO $t_changeset_table ( repo_id, revision, parent, branch, user_id,

@dregad dregad added the bug label Jan 21, 2025
@dregad dregad self-assigned this Jan 21, 2025
@dregad dregad added this to the 2.9.1 milestone Jan 21, 2025
@pfrancois-ACX
Copy link
Author

Hello @dregad,

I've tested your patch for Source.API.php with standard SourceGitea plugin (of course).

All works well ! The changeset database entry for commit 3ba2ee1814 is correctly saved in UTC timezone and the date information displayed in the user interface has the correct timezone included.
image

image

I have also tested the patch with a SVN repositry (it shouldn't have impact as the commit date received is in UTC but just to be safe) and all is okay here as well.

Best regards,

Philippe

@dregad
Copy link
Member

dregad commented Jan 26, 2025

@pfrancois-ACX thanks for the tests and feedback.

Since the solution is quite different from your original submission, I will close this PR. I have opened issue #419 to track the bug, and will commit the fix separately.

@dregad dregad closed this Jan 26, 2025
@dregad dregad removed the bug label Jan 26, 2025
@dregad dregad removed this from the 2.9.1 milestone Jan 26, 2025
dregad added a commit that referenced this pull request Jan 26, 2025
This fixes display of the commit time in the wrong timezone when the
original commit received from source control contains timezone info
as was the case with SourceGitea plugin.

Fixes #419 (originally reported in PR #416)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants