Display ui time with customize time location (#7792)

* display ui time with customize time location

* fix lint

* rename UILocation to DefaultUILocation

* move time related functions to modules/timeutil

* fix tests

* fix tests

* fix build

* fix swagger
This commit is contained in:
Lunny Xiao 2019-08-15 22:46:21 +08:00 committed by GitHub
parent 5a44be627c
commit 85202d4784
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
77 changed files with 770 additions and 662 deletions

View File

@ -547,6 +547,9 @@ MAX_FILES = 5
; Special supported values are ANSIC, UnixDate, RubyDate, RFC822, RFC822Z, RFC850, RFC1123, RFC1123Z, RFC3339, RFC3339Nano, Kitchen, Stamp, StampMilli, StampMicro and StampNano ; Special supported values are ANSIC, UnixDate, RubyDate, RFC822, RFC822Z, RFC850, RFC1123, RFC1123Z, RFC3339, RFC3339Nano, Kitchen, Stamp, StampMilli, StampMicro and StampNano
; For more information about the format see http://golang.org/pkg/time/#pkg-constants ; For more information about the format see http://golang.org/pkg/time/#pkg-constants
FORMAT = FORMAT =
; Location the UI time display i.e. Asia/Shanghai
; Empty means server's location setting
DEFAULT_UI_LOCATION =
[log] [log]
ROOT_PATH = ROOT_PATH =

View File

@ -503,6 +503,10 @@ Two special environment variables are passed to the render command:
- `GITEA_PREFIX_SRC`, which contains the current URL prefix in the `src` path tree. To be used as prefix for links. - `GITEA_PREFIX_SRC`, which contains the current URL prefix in the `src` path tree. To be used as prefix for links.
- `GITEA_PREFIX_RAW`, which contains the current URL prefix in the `raw` path tree. To be used as prefix for image paths. - `GITEA_PREFIX_RAW`, which contains the current URL prefix in the `raw` path tree. To be used as prefix for image paths.
## Time (`time`)
- `FORMAT`: Time format to diplay on UI. i.e. RFC1123 or 2006-01-02 15:04:05
- `DEFAULT_UI_LOCATION`: Default location of time on the UI, so that we can display correct user's time on UI. i.e. Shanghai/Asia
## Other (`other`) ## Other (`other`)
- `SHOW_FOOTER_BRANDING`: **false**: Show Gitea branding in the footer. - `SHOW_FOOTER_BRANDING`: **false**: Show Gitea branding in the footer.

View File

@ -237,7 +237,9 @@ IS_INPUT_FILE = false
- RENDER_COMMAND: 工具的命令行命令及参数。 - RENDER_COMMAND: 工具的命令行命令及参数。
- IS_INPUT_FILE: 输入方式是最后一个参数为文件路径还是从标准输入读取。 - IS_INPUT_FILE: 输入方式是最后一个参数为文件路径还是从标准输入读取。
## Time (`time`)
- `FORMAT`: 显示在界面上的时间格式。比如: RFC1123 或者 2006-01-02 15:04:05
- `DEFAULT_UI_LOCATION`: 默认显示在界面上的时区,默认为本地时区。比如: Asia/Shanghai
## Other (`other`) ## Other (`other`)

View File

@ -20,7 +20,7 @@ import (
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
api "code.gitea.io/gitea/modules/structs" api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/timeutil"
"github.com/Unknwon/com" "github.com/Unknwon/com"
"xorm.io/builder" "xorm.io/builder"
@ -91,9 +91,9 @@ type Action struct {
Comment *Comment `xorm:"-"` Comment *Comment `xorm:"-"`
IsDeleted bool `xorm:"INDEX NOT NULL DEFAULT false"` IsDeleted bool `xorm:"INDEX NOT NULL DEFAULT false"`
RefName string RefName string
IsPrivate bool `xorm:"INDEX NOT NULL DEFAULT false"` IsPrivate bool `xorm:"INDEX NOT NULL DEFAULT false"`
Content string `xorm:"TEXT"` Content string `xorm:"TEXT"`
CreatedUnix util.TimeStamp `xorm:"INDEX created"` CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"`
} }
// GetOpType gets the ActionType of this action. // GetOpType gets the ActionType of this action.

View File

@ -9,7 +9,7 @@ import (
"os" "os"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/timeutil"
"github.com/Unknwon/com" "github.com/Unknwon/com"
) )
@ -26,8 +26,8 @@ const (
type Notice struct { type Notice struct {
ID int64 `xorm:"pk autoincr"` ID int64 `xorm:"pk autoincr"`
Type NoticeType Type NoticeType
Description string `xorm:"TEXT"` Description string `xorm:"TEXT"`
CreatedUnix util.TimeStamp `xorm:"INDEX created"` CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"`
} }
// TrStr returns a translation format string. // TrStr returns a translation format string.

View File

@ -12,7 +12,7 @@ import (
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
api "code.gitea.io/gitea/modules/structs" api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/timeutil"
"github.com/go-xorm/xorm" "github.com/go-xorm/xorm"
gouuid "github.com/satori/go.uuid" gouuid "github.com/satori/go.uuid"
@ -27,9 +27,9 @@ type Attachment struct {
UploaderID int64 `xorm:"INDEX DEFAULT 0"` // Notice: will be zero before this column added UploaderID int64 `xorm:"INDEX DEFAULT 0"` // Notice: will be zero before this column added
CommentID int64 CommentID int64
Name string Name string
DownloadCount int64 `xorm:"DEFAULT 0"` DownloadCount int64 `xorm:"DEFAULT 0"`
Size int64 `xorm:"DEFAULT 0"` Size int64 `xorm:"DEFAULT 0"`
CreatedUnix util.TimeStamp `xorm:"created"` CreatedUnix timeutil.TimeStamp `xorm:"created"`
} }
// IncreaseDownloadCount is update download count + 1 // IncreaseDownloadCount is update download count + 1

View File

@ -11,6 +11,7 @@ import (
"code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/base"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/timeutil"
"code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/util"
"github.com/Unknwon/com" "github.com/Unknwon/com"
@ -30,16 +31,16 @@ type ProtectedBranch struct {
BranchName string `xorm:"UNIQUE(s)"` BranchName string `xorm:"UNIQUE(s)"`
CanPush bool `xorm:"NOT NULL DEFAULT false"` CanPush bool `xorm:"NOT NULL DEFAULT false"`
EnableWhitelist bool EnableWhitelist bool
WhitelistUserIDs []int64 `xorm:"JSON TEXT"` WhitelistUserIDs []int64 `xorm:"JSON TEXT"`
WhitelistTeamIDs []int64 `xorm:"JSON TEXT"` WhitelistTeamIDs []int64 `xorm:"JSON TEXT"`
EnableMergeWhitelist bool `xorm:"NOT NULL DEFAULT false"` EnableMergeWhitelist bool `xorm:"NOT NULL DEFAULT false"`
MergeWhitelistUserIDs []int64 `xorm:"JSON TEXT"` MergeWhitelistUserIDs []int64 `xorm:"JSON TEXT"`
MergeWhitelistTeamIDs []int64 `xorm:"JSON TEXT"` MergeWhitelistTeamIDs []int64 `xorm:"JSON TEXT"`
ApprovalsWhitelistUserIDs []int64 `xorm:"JSON TEXT"` ApprovalsWhitelistUserIDs []int64 `xorm:"JSON TEXT"`
ApprovalsWhitelistTeamIDs []int64 `xorm:"JSON TEXT"` ApprovalsWhitelistTeamIDs []int64 `xorm:"JSON TEXT"`
RequiredApprovals int64 `xorm:"NOT NULL DEFAULT 0"` RequiredApprovals int64 `xorm:"NOT NULL DEFAULT 0"`
CreatedUnix util.TimeStamp `xorm:"created"` CreatedUnix timeutil.TimeStamp `xorm:"created"`
UpdatedUnix util.TimeStamp `xorm:"updated"` UpdatedUnix timeutil.TimeStamp `xorm:"updated"`
} }
// IsProtected returns if the branch is protected // IsProtected returns if the branch is protected
@ -374,13 +375,13 @@ func (repo *Repository) DeleteProtectedBranch(id int64) (err error) {
// DeletedBranch struct // DeletedBranch struct
type DeletedBranch struct { type DeletedBranch struct {
ID int64 `xorm:"pk autoincr"` ID int64 `xorm:"pk autoincr"`
RepoID int64 `xorm:"UNIQUE(s) INDEX NOT NULL"` RepoID int64 `xorm:"UNIQUE(s) INDEX NOT NULL"`
Name string `xorm:"UNIQUE(s) NOT NULL"` Name string `xorm:"UNIQUE(s) NOT NULL"`
Commit string `xorm:"UNIQUE(s) NOT NULL"` Commit string `xorm:"UNIQUE(s) NOT NULL"`
DeletedByID int64 `xorm:"INDEX"` DeletedByID int64 `xorm:"INDEX"`
DeletedBy *User `xorm:"-"` DeletedBy *User `xorm:"-"`
DeletedUnix util.TimeStamp `xorm:"INDEX created"` DeletedUnix timeutil.TimeStamp `xorm:"INDEX created"`
} }
// AddDeletedBranch adds a deleted branch to the database // AddDeletedBranch adds a deleted branch to the database

View File

@ -13,7 +13,7 @@ import (
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
api "code.gitea.io/gitea/modules/structs" api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/timeutil"
"github.com/go-xorm/xorm" "github.com/go-xorm/xorm"
) )
@ -66,8 +66,8 @@ type CommitStatus struct {
Creator *User `xorm:"-"` Creator *User `xorm:"-"`
CreatorID int64 CreatorID int64
CreatedUnix util.TimeStamp `xorm:"INDEX created"` CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"`
UpdatedUnix util.TimeStamp `xorm:"INDEX updated"` UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"`
} }
func (status *CommitStatus) loadRepo(e Engine) (err error) { func (status *CommitStatus) loadRepo(e Engine) (err error) {

View File

@ -17,7 +17,7 @@ import (
"code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/timeutil"
"github.com/go-xorm/xorm" "github.com/go-xorm/xorm"
"github.com/keybase/go-crypto/openpgp" "github.com/keybase/go-crypto/openpgp"
@ -27,14 +27,14 @@ import (
// GPGKey represents a GPG key. // GPGKey represents a GPG key.
type GPGKey struct { type GPGKey struct {
ID int64 `xorm:"pk autoincr"` ID int64 `xorm:"pk autoincr"`
OwnerID int64 `xorm:"INDEX NOT NULL"` OwnerID int64 `xorm:"INDEX NOT NULL"`
KeyID string `xorm:"INDEX CHAR(16) NOT NULL"` KeyID string `xorm:"INDEX CHAR(16) NOT NULL"`
PrimaryKeyID string `xorm:"CHAR(16)"` PrimaryKeyID string `xorm:"CHAR(16)"`
Content string `xorm:"TEXT NOT NULL"` Content string `xorm:"TEXT NOT NULL"`
CreatedUnix util.TimeStamp `xorm:"created"` CreatedUnix timeutil.TimeStamp `xorm:"created"`
ExpiredUnix util.TimeStamp ExpiredUnix timeutil.TimeStamp
AddedUnix util.TimeStamp AddedUnix timeutil.TimeStamp
SubsKey []*GPGKey `xorm:"-"` SubsKey []*GPGKey `xorm:"-"`
Emails []*EmailAddress Emails []*EmailAddress
CanSign bool CanSign bool
@ -51,7 +51,7 @@ type GPGKeyImport struct {
// BeforeInsert will be invoked by XORM before inserting a record // BeforeInsert will be invoked by XORM before inserting a record
func (key *GPGKey) BeforeInsert() { func (key *GPGKey) BeforeInsert() {
key.AddedUnix = util.TimeStampNow() key.AddedUnix = timeutil.TimeStampNow()
} }
// AfterLoad is invoked from XORM after setting the values of all fields of this object. // AfterLoad is invoked from XORM after setting the values of all fields of this object.
@ -223,8 +223,8 @@ func parseSubGPGKey(ownerID int64, primaryID string, pubkey *packet.PublicKey, e
KeyID: pubkey.KeyIdString(), KeyID: pubkey.KeyIdString(),
PrimaryKeyID: primaryID, PrimaryKeyID: primaryID,
Content: content, Content: content,
CreatedUnix: util.TimeStamp(pubkey.CreationTime.Unix()), CreatedUnix: timeutil.TimeStamp(pubkey.CreationTime.Unix()),
ExpiredUnix: util.TimeStamp(expiry.Unix()), ExpiredUnix: timeutil.TimeStamp(expiry.Unix()),
CanSign: pubkey.CanSign(), CanSign: pubkey.CanSign(),
CanEncryptComms: pubkey.PubKeyAlgo.CanEncrypt(), CanEncryptComms: pubkey.PubKeyAlgo.CanEncrypt(),
CanEncryptStorage: pubkey.PubKeyAlgo.CanEncrypt(), CanEncryptStorage: pubkey.PubKeyAlgo.CanEncrypt(),
@ -301,8 +301,8 @@ func parseGPGKey(ownerID int64, e *openpgp.Entity) (*GPGKey, error) {
KeyID: pubkey.KeyIdString(), KeyID: pubkey.KeyIdString(),
PrimaryKeyID: "", PrimaryKeyID: "",
Content: content, Content: content,
CreatedUnix: util.TimeStamp(pubkey.CreationTime.Unix()), CreatedUnix: timeutil.TimeStamp(pubkey.CreationTime.Unix()),
ExpiredUnix: util.TimeStamp(expiry.Unix()), ExpiredUnix: timeutil.TimeStamp(expiry.Unix()),
Emails: emails, Emails: emails,
SubsKey: subkeys, SubsKey: subkeys,
CanSign: pubkey.CanSign(), CanSign: pubkey.CanSign(),

View File

@ -8,7 +8,7 @@ import (
"testing" "testing"
"time" "time"
"code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/timeutil"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
@ -112,7 +112,7 @@ MkM/fdpyc2hY7Dl/+qFmN5MG5yGmMpQcX+RNNR222ibNC1D3wg==
key := &GPGKey{ key := &GPGKey{
KeyID: pubkey.KeyIdString(), KeyID: pubkey.KeyIdString(),
Content: content, Content: content,
CreatedUnix: util.TimeStamp(pubkey.CreationTime.Unix()), CreatedUnix: timeutil.TimeStamp(pubkey.CreationTime.Unix()),
CanSign: pubkey.CanSign(), CanSign: pubkey.CanSign(),
CanEncryptComms: pubkey.PubKeyAlgo.CanEncrypt(), CanEncryptComms: pubkey.PubKeyAlgo.CanEncrypt(),
CanEncryptStorage: pubkey.PubKeyAlgo.CanEncrypt(), CanEncryptStorage: pubkey.PubKeyAlgo.CanEncrypt(),
@ -122,7 +122,7 @@ MkM/fdpyc2hY7Dl/+qFmN5MG5yGmMpQcX+RNNR222ibNC1D3wg==
cannotsignkey := &GPGKey{ cannotsignkey := &GPGKey{
KeyID: pubkey.KeyIdString(), KeyID: pubkey.KeyIdString(),
Content: content, Content: content,
CreatedUnix: util.TimeStamp(pubkey.CreationTime.Unix()), CreatedUnix: timeutil.TimeStamp(pubkey.CreationTime.Unix()),
CanSign: false, CanSign: false,
CanEncryptComms: false, CanEncryptComms: false,
CanEncryptStorage: false, CanEncryptStorage: false,

View File

@ -16,6 +16,7 @@ import (
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
api "code.gitea.io/gitea/modules/structs" api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/timeutil"
"code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/util"
"github.com/Unknwon/com" "github.com/Unknwon/com"
@ -49,11 +50,11 @@ type Issue struct {
NumComments int NumComments int
Ref string Ref string
DeadlineUnix util.TimeStamp `xorm:"INDEX"` DeadlineUnix timeutil.TimeStamp `xorm:"INDEX"`
CreatedUnix util.TimeStamp `xorm:"INDEX created"` CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"`
UpdatedUnix util.TimeStamp `xorm:"INDEX updated"` UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"`
ClosedUnix util.TimeStamp `xorm:"INDEX"` ClosedUnix timeutil.TimeStamp `xorm:"INDEX"`
Attachments []*Attachment `xorm:"-"` Attachments []*Attachment `xorm:"-"`
Comments []*Comment `xorm:"-"` Comments []*Comment `xorm:"-"`
@ -90,7 +91,7 @@ func (issue *Issue) loadTotalTimes(e Engine) (err error) {
// IsOverdue checks if the issue is overdue // IsOverdue checks if the issue is overdue
func (issue *Issue) IsOverdue() bool { func (issue *Issue) IsOverdue() bool {
return util.TimeStampNow() >= issue.DeadlineUnix return timeutil.TimeStampNow() >= issue.DeadlineUnix
} }
// LoadRepo loads issue's repository // LoadRepo loads issue's repository
@ -744,7 +745,7 @@ func (issue *Issue) changeStatus(e *xorm.Session, doer *User, isClosed bool) (er
issue.IsClosed = isClosed issue.IsClosed = isClosed
if isClosed { if isClosed {
issue.ClosedUnix = util.TimeStampNow() issue.ClosedUnix = timeutil.TimeStampNow()
} else { } else {
issue.ClosedUnix = 0 issue.ClosedUnix = 0
} }
@ -991,7 +992,7 @@ func (issue *Issue) GetTasksDone() int {
} }
// GetLastEventTimestamp returns the last user visible event timestamp, either the creation of this issue or the close. // GetLastEventTimestamp returns the last user visible event timestamp, either the creation of this issue or the close.
func (issue *Issue) GetLastEventTimestamp() util.TimeStamp { func (issue *Issue) GetLastEventTimestamp() timeutil.TimeStamp {
if issue.IsClosed { if issue.IsClosed {
return issue.ClosedUnix return issue.ClosedUnix
} }
@ -1794,7 +1795,7 @@ func UpdateIssue(issue *Issue) error {
} }
// UpdateIssueDeadline updates an issue deadline and adds comments. Setting a deadline to 0 means deleting it. // UpdateIssueDeadline updates an issue deadline and adds comments. Setting a deadline to 0 means deleting it.
func UpdateIssueDeadline(issue *Issue, deadlineUnix util.TimeStamp, doer *User) (err error) { func UpdateIssueDeadline(issue *Issue, deadlineUnix timeutil.TimeStamp, doer *User) (err error) {
// if the deadline hasn't changed do nothing // if the deadline hasn't changed do nothing
if issue.DeadlineUnix == deadlineUnix { if issue.DeadlineUnix == deadlineUnix {

View File

@ -12,17 +12,16 @@ import (
"strings" "strings"
"code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/markup"
"code.gitea.io/gitea/modules/markup/markdown" "code.gitea.io/gitea/modules/markup/markdown"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/timeutil"
"github.com/Unknwon/com" "github.com/Unknwon/com"
"github.com/go-xorm/xorm" "github.com/go-xorm/xorm"
"xorm.io/builder" "xorm.io/builder"
api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/markup"
"code.gitea.io/gitea/modules/util"
) )
// CommentType defines whether a comment is just a simple comment, an action (like close) or a reference. // CommentType defines whether a comment is just a simple comment, an action (like close) or a reference.
@ -130,8 +129,8 @@ type Comment struct {
// Path represents the 4 lines of code cemented by this comment // Path represents the 4 lines of code cemented by this comment
Patch string `xorm:"TEXT"` Patch string `xorm:"TEXT"`
CreatedUnix util.TimeStamp `xorm:"INDEX created"` CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"`
UpdatedUnix util.TimeStamp `xorm:"INDEX updated"` UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"`
// Reference issue in commit message // Reference issue in commit message
CommitSHA string `xorm:"VARCHAR(40)"` CommitSHA string `xorm:"VARCHAR(40)"`
@ -711,7 +710,7 @@ func createAssigneeComment(e *xorm.Session, doer *User, repo *Repository, issue
}) })
} }
func createDeadlineComment(e *xorm.Session, doer *User, issue *Issue, newDeadlineUnix util.TimeStamp) (*Comment, error) { func createDeadlineComment(e *xorm.Session, doer *User, issue *Issue, newDeadlineUnix timeutil.TimeStamp) (*Comment, error) {
var content string var content string
var commentType CommentType var commentType CommentType

View File

@ -7,17 +7,17 @@ package models
import ( import (
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/timeutil"
) )
// IssueDependency represents an issue dependency // IssueDependency represents an issue dependency
type IssueDependency struct { type IssueDependency struct {
ID int64 `xorm:"pk autoincr"` ID int64 `xorm:"pk autoincr"`
UserID int64 `xorm:"NOT NULL"` UserID int64 `xorm:"NOT NULL"`
IssueID int64 `xorm:"UNIQUE(issue_dependency) NOT NULL"` IssueID int64 `xorm:"UNIQUE(issue_dependency) NOT NULL"`
DependencyID int64 `xorm:"UNIQUE(issue_dependency) NOT NULL"` DependencyID int64 `xorm:"UNIQUE(issue_dependency) NOT NULL"`
CreatedUnix util.TimeStamp `xorm:"created"` CreatedUnix timeutil.TimeStamp `xorm:"created"`
UpdatedUnix util.TimeStamp `xorm:"updated"` UpdatedUnix timeutil.TimeStamp `xorm:"updated"`
} }
// DependencyType Defines Dependency Type Constants // DependencyType Defines Dependency Type Constants

View File

@ -10,7 +10,8 @@ import (
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
api "code.gitea.io/gitea/modules/structs" api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/timeutil"
"github.com/go-xorm/xorm" "github.com/go-xorm/xorm"
) )
@ -29,8 +30,8 @@ type Milestone struct {
IsOverdue bool `xorm:"-"` IsOverdue bool `xorm:"-"`
DeadlineString string `xorm:"-"` DeadlineString string `xorm:"-"`
DeadlineUnix util.TimeStamp DeadlineUnix timeutil.TimeStamp
ClosedDateUnix util.TimeStamp ClosedDateUnix timeutil.TimeStamp
TotalTrackedTime int64 `xorm:"-"` TotalTrackedTime int64 `xorm:"-"`
} }
@ -53,7 +54,7 @@ func (m *Milestone) AfterLoad() {
} }
m.DeadlineString = m.DeadlineUnix.Format("2006-01-02") m.DeadlineString = m.DeadlineUnix.Format("2006-01-02")
if util.TimeStampNow() >= m.DeadlineUnix { if timeutil.TimeStampNow() >= m.DeadlineUnix {
m.IsOverdue = true m.IsOverdue = true
} }
} }

View File

@ -10,7 +10,7 @@ import (
"time" "time"
api "code.gitea.io/gitea/modules/structs" api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/timeutil"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
@ -29,7 +29,7 @@ func TestMilestone_APIFormat(t *testing.T) {
IsClosed: false, IsClosed: false,
NumOpenIssues: 5, NumOpenIssues: 5,
NumClosedIssues: 6, NumClosedIssues: 6,
DeadlineUnix: util.TimeStamp(time.Date(2000, time.January, 1, 0, 0, 0, 0, time.UTC).Unix()), DeadlineUnix: timeutil.TimeStamp(time.Date(2000, time.January, 1, 0, 0, 0, 0, time.UTC).Unix()),
} }
assert.Equal(t, api.Milestone{ assert.Equal(t, api.Milestone{
ID: milestone.ID, ID: milestone.ID,
@ -237,7 +237,7 @@ func TestChangeMilestoneIssueStats(t *testing.T) {
"is_closed=0").(*Issue) "is_closed=0").(*Issue)
issue.IsClosed = true issue.IsClosed = true
issue.ClosedUnix = util.TimeStampNow() issue.ClosedUnix = timeutil.TimeStampNow()
_, err := x.Cols("is_closed", "closed_unix").Update(issue) _, err := x.Cols("is_closed", "closed_unix").Update(issue)
assert.NoError(t, err) assert.NoError(t, err)
assert.NoError(t, changeMilestoneIssueStats(x.NewSession(), issue)) assert.NoError(t, changeMilestoneIssueStats(x.NewSession(), issue))

View File

@ -9,7 +9,7 @@ import (
"fmt" "fmt"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/timeutil"
"github.com/go-xorm/xorm" "github.com/go-xorm/xorm"
"xorm.io/builder" "xorm.io/builder"
@ -17,13 +17,13 @@ import (
// Reaction represents a reactions on issues and comments. // Reaction represents a reactions on issues and comments.
type Reaction struct { type Reaction struct {
ID int64 `xorm:"pk autoincr"` ID int64 `xorm:"pk autoincr"`
Type string `xorm:"INDEX UNIQUE(s) NOT NULL"` Type string `xorm:"INDEX UNIQUE(s) NOT NULL"`
IssueID int64 `xorm:"INDEX UNIQUE(s) NOT NULL"` IssueID int64 `xorm:"INDEX UNIQUE(s) NOT NULL"`
CommentID int64 `xorm:"INDEX UNIQUE(s)"` CommentID int64 `xorm:"INDEX UNIQUE(s)"`
UserID int64 `xorm:"INDEX UNIQUE(s) NOT NULL"` UserID int64 `xorm:"INDEX UNIQUE(s) NOT NULL"`
User *User `xorm:"-"` User *User `xorm:"-"`
CreatedUnix util.TimeStamp `xorm:"INDEX created"` CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"`
} }
// FindReactionsOptions describes the conditions to Find reactions // FindReactionsOptions describes the conditions to Find reactions

View File

@ -8,15 +8,15 @@ import (
"fmt" "fmt"
"time" "time"
"code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/timeutil"
) )
// Stopwatch represents a stopwatch for time tracking. // Stopwatch represents a stopwatch for time tracking.
type Stopwatch struct { type Stopwatch struct {
ID int64 `xorm:"pk autoincr"` ID int64 `xorm:"pk autoincr"`
IssueID int64 `xorm:"INDEX"` IssueID int64 `xorm:"INDEX"`
UserID int64 `xorm:"INDEX"` UserID int64 `xorm:"INDEX"`
CreatedUnix util.TimeStamp `xorm:"created"` CreatedUnix timeutil.TimeStamp `xorm:"created"`
} }
func getStopwatch(e Engine, userID, issueID int64) (sw *Stopwatch, exists bool, err error) { func getStopwatch(e Engine, userID, issueID int64) (sw *Stopwatch, exists bool, err error) {

View File

@ -3,7 +3,7 @@ package models
import ( import (
"testing" "testing"
"code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/timeutil"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
@ -63,7 +63,7 @@ func TestCreateOrStopIssueStopwatch(t *testing.T) {
assert.NoError(t, CreateOrStopIssueStopwatch(user3, issue1)) assert.NoError(t, CreateOrStopIssueStopwatch(user3, issue1))
sw := AssertExistsAndLoadBean(t, &Stopwatch{UserID: 3, IssueID: 1}).(*Stopwatch) sw := AssertExistsAndLoadBean(t, &Stopwatch{UserID: 3, IssueID: 1}).(*Stopwatch)
assert.Equal(t, true, sw.CreatedUnix <= util.TimeStampNow()) assert.Equal(t, true, sw.CreatedUnix <= timeutil.TimeStampNow())
assert.NoError(t, CreateOrStopIssueStopwatch(user2, issue2)) assert.NoError(t, CreateOrStopIssueStopwatch(user2, issue2))
AssertNotExistsBean(t, &Stopwatch{UserID: 2, IssueID: 2}) AssertNotExistsBean(t, &Stopwatch{UserID: 2, IssueID: 2})

View File

@ -26,7 +26,7 @@ type TrackedTime struct {
// AfterLoad is invoked from XORM after setting the values of all fields of this object. // AfterLoad is invoked from XORM after setting the values of all fields of this object.
func (t *TrackedTime) AfterLoad() { func (t *TrackedTime) AfterLoad() {
t.Created = time.Unix(t.CreatedUnix, 0).In(setting.UILocation) t.Created = time.Unix(t.CreatedUnix, 0).In(setting.DefaultUILocation)
} }
// APIFormat converts TrackedTime to API format // APIFormat converts TrackedTime to API format

View File

@ -4,16 +4,16 @@
package models package models
import "code.gitea.io/gitea/modules/util" import "code.gitea.io/gitea/modules/timeutil"
// IssueWatch is connection request for receiving issue notification. // IssueWatch is connection request for receiving issue notification.
type IssueWatch struct { type IssueWatch struct {
ID int64 `xorm:"pk autoincr"` ID int64 `xorm:"pk autoincr"`
UserID int64 `xorm:"UNIQUE(watch) NOT NULL"` UserID int64 `xorm:"UNIQUE(watch) NOT NULL"`
IssueID int64 `xorm:"UNIQUE(watch) NOT NULL"` IssueID int64 `xorm:"UNIQUE(watch) NOT NULL"`
IsWatching bool `xorm:"NOT NULL"` IsWatching bool `xorm:"NOT NULL"`
CreatedUnix util.TimeStamp `xorm:"created NOT NULL"` CreatedUnix timeutil.TimeStamp `xorm:"created NOT NULL"`
UpdatedUnix util.TimeStamp `xorm:"updated NOT NULL"` UpdatedUnix timeutil.TimeStamp `xorm:"updated NOT NULL"`
} }
// CreateOrUpdateIssueWatch set watching for a user and issue // CreateOrUpdateIssueWatch set watching for a user and issue

View File

@ -7,17 +7,17 @@ import (
"fmt" "fmt"
"io" "io"
"code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/timeutil"
) )
// LFSMetaObject stores metadata for LFS tracked files. // LFSMetaObject stores metadata for LFS tracked files.
type LFSMetaObject struct { type LFSMetaObject struct {
ID int64 `xorm:"pk autoincr"` ID int64 `xorm:"pk autoincr"`
Oid string `xorm:"UNIQUE(s) INDEX NOT NULL"` Oid string `xorm:"UNIQUE(s) INDEX NOT NULL"`
Size int64 `xorm:"NOT NULL"` Size int64 `xorm:"NOT NULL"`
RepositoryID int64 `xorm:"UNIQUE(s) INDEX NOT NULL"` RepositoryID int64 `xorm:"UNIQUE(s) INDEX NOT NULL"`
Existing bool `xorm:"-"` Existing bool `xorm:"-"`
CreatedUnix util.TimeStamp `xorm:"created"` CreatedUnix timeutil.TimeStamp `xorm:"created"`
} }
// Pointer returns the string representation of an LFS pointer file // Pointer returns the string representation of an LFS pointer file

View File

@ -14,16 +14,16 @@ import (
"regexp" "regexp"
"strings" "strings"
"github.com/Unknwon/com"
"github.com/go-xorm/xorm"
"xorm.io/core"
"code.gitea.io/gitea/modules/auth/ldap" "code.gitea.io/gitea/modules/auth/ldap"
"code.gitea.io/gitea/modules/auth/oauth2" "code.gitea.io/gitea/modules/auth/oauth2"
"code.gitea.io/gitea/modules/auth/pam" "code.gitea.io/gitea/modules/auth/pam"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/timeutil"
"github.com/Unknwon/com"
"github.com/go-xorm/xorm"
"xorm.io/core"
) )
// LoginType represents an login type. // LoginType represents an login type.
@ -148,8 +148,8 @@ type LoginSource struct {
IsSyncEnabled bool `xorm:"INDEX NOT NULL DEFAULT false"` IsSyncEnabled bool `xorm:"INDEX NOT NULL DEFAULT false"`
Cfg core.Conversion `xorm:"TEXT"` Cfg core.Conversion `xorm:"TEXT"`
CreatedUnix util.TimeStamp `xorm:"INDEX created"` CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"`
UpdatedUnix util.TimeStamp `xorm:"INDEX updated"` UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"`
} }
// Cell2Int64 converts a xorm.Cell type to int64, // Cell2Int64 converts a xorm.Cell type to int64,

View File

@ -16,6 +16,7 @@ import (
"code.gitea.io/gitea/modules/markup" "code.gitea.io/gitea/modules/markup"
"code.gitea.io/gitea/modules/markup/markdown" "code.gitea.io/gitea/modules/markup/markdown"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/timeutil"
"gopkg.in/gomail.v2" "gopkg.in/gomail.v2"
) )
@ -47,8 +48,8 @@ func SendTestMail(email string) error {
func SendUserMail(language string, u *User, tpl base.TplName, code, subject, info string) { func SendUserMail(language string, u *User, tpl base.TplName, code, subject, info string) {
data := map[string]interface{}{ data := map[string]interface{}{
"DisplayName": u.DisplayName(), "DisplayName": u.DisplayName(),
"ActiveCodeLives": base.MinutesToFriendly(setting.Service.ActiveCodeLives, language), "ActiveCodeLives": timeutil.MinutesToFriendly(setting.Service.ActiveCodeLives, language),
"ResetPwdCodeLives": base.MinutesToFriendly(setting.Service.ResetPwdCodeLives, language), "ResetPwdCodeLives": timeutil.MinutesToFriendly(setting.Service.ResetPwdCodeLives, language),
"Code": code, "Code": code,
} }
@ -85,7 +86,7 @@ func SendResetPasswordMail(locale Locale, u *User) {
func SendActivateEmailMail(locale Locale, u *User, email *EmailAddress) { func SendActivateEmailMail(locale Locale, u *User, email *EmailAddress) {
data := map[string]interface{}{ data := map[string]interface{}{
"DisplayName": u.DisplayName(), "DisplayName": u.DisplayName(),
"ActiveCodeLives": base.MinutesToFriendly(setting.Service.ActiveCodeLives, locale.Language()), "ActiveCodeLives": timeutil.MinutesToFriendly(setting.Service.ActiveCodeLives, locale.Language()),
"Code": u.GenerateEmailActivateCode(email.Email), "Code": u.GenerateEmailActivateCode(email.Email),
"Email": email.Email, "Email": email.Email,
} }

View File

@ -7,7 +7,7 @@ package migrations
import ( import (
"fmt" "fmt"
"code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/timeutil"
"github.com/go-xorm/xorm" "github.com/go-xorm/xorm"
) )
@ -19,7 +19,7 @@ func addPullRequestOptions(x *xorm.Engine) error {
RepoID int64 `xorm:"INDEX(s)"` RepoID int64 `xorm:"INDEX(s)"`
Type int `xorm:"INDEX(s)"` Type int `xorm:"INDEX(s)"`
Config map[string]interface{} `xorm:"JSON"` Config map[string]interface{} `xorm:"JSON"`
CreatedUnix util.TimeStamp `xorm:"INDEX CREATED"` CreatedUnix timeutil.TimeStamp `xorm:"INDEX CREATED"`
} }
sess := x.NewSession() sess := x.NewSession()

View File

@ -7,7 +7,7 @@ package migrations
import ( import (
"fmt" "fmt"
"code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/timeutil"
"github.com/go-xorm/xorm" "github.com/go-xorm/xorm"
) )
@ -15,7 +15,7 @@ import (
func addIssueClosedTime(x *xorm.Engine) error { func addIssueClosedTime(x *xorm.Engine) error {
// Issue see models/issue.go // Issue see models/issue.go
type Issue struct { type Issue struct {
ClosedUnix util.TimeStamp `xorm:"INDEX"` ClosedUnix timeutil.TimeStamp `xorm:"INDEX"`
} }
if err := x.Sync2(new(Issue)); err != nil { if err := x.Sync2(new(Issue)); err != nil {

View File

@ -5,7 +5,7 @@
package migrations package migrations
import ( import (
"code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/timeutil"
"github.com/go-xorm/xorm" "github.com/go-xorm/xorm"
) )
@ -27,10 +27,10 @@ func addMultipleAssignees(x *xorm.Engine) error {
IsPull bool `xorm:"INDEX"` // Indicates whether is a pull request or not. IsPull bool `xorm:"INDEX"` // Indicates whether is a pull request or not.
NumComments int NumComments int
DeadlineUnix util.TimeStamp `xorm:"INDEX"` DeadlineUnix timeutil.TimeStamp `xorm:"INDEX"`
CreatedUnix util.TimeStamp `xorm:"INDEX created"` CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"`
UpdatedUnix util.TimeStamp `xorm:"INDEX updated"` UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"`
ClosedUnix util.TimeStamp `xorm:"INDEX"` ClosedUnix timeutil.TimeStamp `xorm:"INDEX"`
} }
// Updated the comment table // Updated the comment table
@ -53,8 +53,8 @@ func addMultipleAssignees(x *xorm.Engine) error {
Content string `xorm:"TEXT"` Content string `xorm:"TEXT"`
RenderedContent string `xorm:"-"` RenderedContent string `xorm:"-"`
CreatedUnix util.TimeStamp `xorm:"INDEX created"` CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"`
UpdatedUnix util.TimeStamp `xorm:"INDEX updated"` UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"`
// Reference issue in commit message // Reference issue in commit message
CommitSHA string `xorm:"VARCHAR(40)"` CommitSHA string `xorm:"VARCHAR(40)"`

View File

@ -1,7 +1,8 @@
package migrations package migrations
import ( import (
"code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/timeutil"
"github.com/go-xorm/xorm" "github.com/go-xorm/xorm"
) )
@ -12,8 +13,8 @@ func addU2FReg(x *xorm.Engine) error {
UserID int64 `xorm:"INDEX"` UserID int64 `xorm:"INDEX"`
Raw []byte Raw []byte
Counter uint32 Counter uint32
CreatedUnix util.TimeStamp `xorm:"INDEX created"` CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"`
UpdatedUnix util.TimeStamp `xorm:"INDEX updated"` UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"`
} }
return x.Sync2(&U2FRegistration{}) return x.Sync2(&U2FRegistration{})
} }

View File

@ -8,11 +8,11 @@ import (
"crypto/sha256" "crypto/sha256"
"fmt" "fmt"
"code.gitea.io/gitea/modules/generate"
"code.gitea.io/gitea/modules/timeutil"
"github.com/go-xorm/xorm" "github.com/go-xorm/xorm"
"golang.org/x/crypto/pbkdf2" "golang.org/x/crypto/pbkdf2"
"code.gitea.io/gitea/modules/generate"
"code.gitea.io/gitea/modules/util"
) )
func addScratchHash(x *xorm.Engine) error { func addScratchHash(x *xorm.Engine) error {
@ -24,9 +24,9 @@ func addScratchHash(x *xorm.Engine) error {
ScratchToken string ScratchToken string
ScratchSalt string ScratchSalt string
ScratchHash string ScratchHash string
LastUsedPasscode string `xorm:"VARCHAR(10)"` LastUsedPasscode string `xorm:"VARCHAR(10)"`
CreatedUnix util.TimeStamp `xorm:"INDEX created"` CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"`
UpdatedUnix util.TimeStamp `xorm:"INDEX updated"` UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"`
} }
if err := x.Sync2(new(TwoFactor)); err != nil { if err := x.Sync2(new(TwoFactor)); err != nil {

View File

@ -7,7 +7,7 @@ package migrations
import ( import (
"fmt" "fmt"
"code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/timeutil"
"github.com/go-xorm/xorm" "github.com/go-xorm/xorm"
) )
@ -20,8 +20,8 @@ func addReview(x *xorm.Engine) error {
ReviewerID int64 `xorm:"index"` ReviewerID int64 `xorm:"index"`
IssueID int64 `xorm:"index"` IssueID int64 `xorm:"index"`
Content string Content string
CreatedUnix util.TimeStamp `xorm:"INDEX created"` CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"`
UpdatedUnix util.TimeStamp `xorm:"INDEX updated"` UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"`
} }
if err := x.Sync2(new(Review)); err != nil { if err := x.Sync2(new(Review)); err != nil {

View File

@ -7,7 +7,7 @@ package migrations
import ( import (
"fmt" "fmt"
"code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/timeutil"
"github.com/go-xorm/xorm" "github.com/go-xorm/xorm"
) )
@ -19,7 +19,7 @@ func addPullRequestRebaseWithMerge(x *xorm.Engine) error {
RepoID int64 `xorm:"INDEX(s)"` RepoID int64 `xorm:"INDEX(s)"`
Type int `xorm:"INDEX(s)"` Type int `xorm:"INDEX(s)"`
Config map[string]interface{} `xorm:"JSON"` Config map[string]interface{} `xorm:"JSON"`
CreatedUnix util.TimeStamp `xorm:"INDEX CREATED"` CreatedUnix timeutil.TimeStamp `xorm:"INDEX CREATED"`
} }
sess := x.NewSession() sess := x.NewSession()

View File

@ -5,7 +5,7 @@
package migrations package migrations
import ( import (
"code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/timeutil"
"github.com/go-xorm/xorm" "github.com/go-xorm/xorm"
) )
@ -19,9 +19,9 @@ func addUploaderIDForAttachment(x *xorm.Engine) error {
UploaderID int64 `xorm:"INDEX DEFAULT 0"` UploaderID int64 `xorm:"INDEX DEFAULT 0"`
CommentID int64 CommentID int64
Name string Name string
DownloadCount int64 `xorm:"DEFAULT 0"` DownloadCount int64 `xorm:"DEFAULT 0"`
Size int64 `xorm:"DEFAULT 0"` Size int64 `xorm:"DEFAULT 0"`
CreatedUnix util.TimeStamp `xorm:"created"` CreatedUnix timeutil.TimeStamp `xorm:"created"`
} }
return x.Sync2(new(Attachment)) return x.Sync2(new(Attachment))

View File

@ -7,11 +7,11 @@ package migrations
import ( import (
"fmt" "fmt"
"github.com/go-xorm/xorm"
"code.gitea.io/gitea/modules/generate" "code.gitea.io/gitea/modules/generate"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/timeutil"
"github.com/go-xorm/xorm"
) )
func hashAppToken(x *xorm.Engine) error { func hashAppToken(x *xorm.Engine) error {
@ -26,10 +26,10 @@ func hashAppToken(x *xorm.Engine) error {
TokenSalt string TokenSalt string
TokenLastEight string `xorm:"token_last_eight"` TokenLastEight string `xorm:"token_last_eight"`
CreatedUnix util.TimeStamp `xorm:"INDEX created"` CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"`
UpdatedUnix util.TimeStamp `xorm:"INDEX updated"` UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"`
HasRecentActivity bool `xorm:"-"` HasRecentActivity bool `xorm:"-"`
HasUsed bool `xorm:"-"` HasUsed bool `xorm:"-"`
} }
// First remove the index // First remove the index

View File

@ -7,7 +7,7 @@ package models
import ( import (
"fmt" "fmt"
"code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/timeutil"
) )
type ( type (
@ -52,8 +52,8 @@ type Notification struct {
Issue *Issue `xorm:"-"` Issue *Issue `xorm:"-"`
Repository *Repository `xorm:"-"` Repository *Repository `xorm:"-"`
CreatedUnix util.TimeStamp `xorm:"created INDEX NOT NULL"` CreatedUnix timeutil.TimeStamp `xorm:"created INDEX NOT NULL"`
UpdatedUnix util.TimeStamp `xorm:"updated INDEX NOT NULL"` UpdatedUnix timeutil.TimeStamp `xorm:"updated INDEX NOT NULL"`
} }
// CreateOrUpdateIssueNotifications creates an issue notification // CreateOrUpdateIssueNotifications creates an issue notification

View File

@ -11,15 +11,14 @@ import (
"net/url" "net/url"
"time" "time"
"github.com/go-xorm/xorm"
uuid "github.com/satori/go.uuid"
"code.gitea.io/gitea/modules/secret" "code.gitea.io/gitea/modules/secret"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/timeutil"
"github.com/Unknwon/com" "github.com/Unknwon/com"
"github.com/dgrijalva/jwt-go" "github.com/dgrijalva/jwt-go"
"github.com/go-xorm/xorm"
uuid "github.com/satori/go.uuid"
"golang.org/x/crypto/bcrypt" "golang.org/x/crypto/bcrypt"
) )
@ -36,8 +35,8 @@ type OAuth2Application struct {
RedirectURIs []string `xorm:"redirect_uris JSON TEXT"` RedirectURIs []string `xorm:"redirect_uris JSON TEXT"`
CreatedUnix util.TimeStamp `xorm:"INDEX created"` CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"`
UpdatedUnix util.TimeStamp `xorm:"INDEX updated"` UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"`
} }
// TableName sets the table name to `oauth2_application` // TableName sets the table name to `oauth2_application`
@ -264,7 +263,7 @@ type OAuth2AuthorizationCode struct {
CodeChallenge string CodeChallenge string
CodeChallengeMethod string CodeChallengeMethod string
RedirectURI string RedirectURI string
ValidUntil util.TimeStamp `xorm:"index"` ValidUntil timeutil.TimeStamp `xorm:"index"`
} }
// TableName sets the table name to `oauth2_authorization_code` // TableName sets the table name to `oauth2_authorization_code`
@ -348,8 +347,8 @@ type OAuth2Grant struct {
Application *OAuth2Application `xorm:"-"` Application *OAuth2Application `xorm:"-"`
ApplicationID int64 `xorm:"INDEX unique(user_application)"` ApplicationID int64 `xorm:"INDEX unique(user_application)"`
Counter int64 `xorm:"NOT NULL DEFAULT 1"` Counter int64 `xorm:"NOT NULL DEFAULT 1"`
CreatedUnix util.TimeStamp `xorm:"created"` CreatedUnix timeutil.TimeStamp `xorm:"created"`
UpdatedUnix util.TimeStamp `xorm:"updated"` UpdatedUnix timeutil.TimeStamp `xorm:"updated"`
} }
// TableName sets the table name to `oauth2_grant` // TableName sets the table name to `oauth2_grant`

View File

@ -23,7 +23,7 @@ import (
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
api "code.gitea.io/gitea/modules/structs" api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/sync" "code.gitea.io/gitea/modules/sync"
"code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/timeutil"
"github.com/Unknwon/com" "github.com/Unknwon/com"
"github.com/go-xorm/xorm" "github.com/go-xorm/xorm"
@ -72,11 +72,11 @@ type PullRequest struct {
ProtectedBranch *ProtectedBranch `xorm:"-"` ProtectedBranch *ProtectedBranch `xorm:"-"`
MergeBase string `xorm:"VARCHAR(40)"` MergeBase string `xorm:"VARCHAR(40)"`
HasMerged bool `xorm:"INDEX"` HasMerged bool `xorm:"INDEX"`
MergedCommitID string `xorm:"VARCHAR(40)"` MergedCommitID string `xorm:"VARCHAR(40)"`
MergerID int64 `xorm:"INDEX"` MergerID int64 `xorm:"INDEX"`
Merger *User `xorm:"-"` Merger *User `xorm:"-"`
MergedUnix util.TimeStamp `xorm:"updated INDEX"` MergedUnix timeutil.TimeStamp `xorm:"updated INDEX"`
} }
// Note: don't try to get Issue because will end up recursive querying. // Note: don't try to get Issue because will end up recursive querying.
@ -443,7 +443,7 @@ func (pr *PullRequest) manuallyMerged() bool {
} }
if commit != nil { if commit != nil {
pr.MergedCommitID = commit.ID.String() pr.MergedCommitID = commit.ID.String()
pr.MergedUnix = util.TimeStamp(commit.Author.When.Unix()) pr.MergedUnix = timeutil.TimeStamp(commit.Author.When.Unix())
pr.Status = PullRequestStatusManuallyMerged pr.Status = PullRequestStatusManuallyMerged
merger, _ := GetUserByEmail(commit.Author.Email) merger, _ := GetUserByEmail(commit.Author.Email)

View File

@ -14,7 +14,7 @@ import (
"code.gitea.io/gitea/modules/process" "code.gitea.io/gitea/modules/process"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
api "code.gitea.io/gitea/modules/structs" api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/timeutil"
"xorm.io/builder" "xorm.io/builder"
) )
@ -32,13 +32,13 @@ type Release struct {
Title string Title string
Sha1 string `xorm:"VARCHAR(40)"` Sha1 string `xorm:"VARCHAR(40)"`
NumCommits int64 NumCommits int64
NumCommitsBehind int64 `xorm:"-"` NumCommitsBehind int64 `xorm:"-"`
Note string `xorm:"TEXT"` Note string `xorm:"TEXT"`
IsDraft bool `xorm:"NOT NULL DEFAULT false"` IsDraft bool `xorm:"NOT NULL DEFAULT false"`
IsPrerelease bool `xorm:"NOT NULL DEFAULT false"` IsPrerelease bool `xorm:"NOT NULL DEFAULT false"`
IsTag bool `xorm:"NOT NULL DEFAULT false"` IsTag bool `xorm:"NOT NULL DEFAULT false"`
Attachments []*Attachment `xorm:"-"` Attachments []*Attachment `xorm:"-"`
CreatedUnix util.TimeStamp `xorm:"INDEX"` CreatedUnix timeutil.TimeStamp `xorm:"INDEX"`
} }
func (r *Release) loadAttributes(e Engine) error { func (r *Release) loadAttributes(e Engine) error {
@ -137,13 +137,13 @@ func createTag(gitRepo *git.Repository, rel *Release) error {
} }
rel.Sha1 = commit.ID.String() rel.Sha1 = commit.ID.String()
rel.CreatedUnix = util.TimeStamp(commit.Author.When.Unix()) rel.CreatedUnix = timeutil.TimeStamp(commit.Author.When.Unix())
rel.NumCommits, err = commit.CommitsCount() rel.NumCommits, err = commit.CommitsCount()
if err != nil { if err != nil {
return fmt.Errorf("CommitsCount: %v", err) return fmt.Errorf("CommitsCount: %v", err)
} }
} else { } else {
rel.CreatedUnix = util.TimeStampNow() rel.CreatedUnix = timeutil.TimeStampNow()
} }
return nil return nil
} }

View File

@ -34,7 +34,7 @@ import (
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
api "code.gitea.io/gitea/modules/structs" api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/sync" "code.gitea.io/gitea/modules/sync"
"code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/timeutil"
"github.com/Unknwon/com" "github.com/Unknwon/com"
"github.com/go-xorm/xorm" "github.com/go-xorm/xorm"
@ -175,8 +175,8 @@ type Repository struct {
// Avatar: ID(10-20)-md5(32) - must fit into 64 symbols // Avatar: ID(10-20)-md5(32) - must fit into 64 symbols
Avatar string `xorm:"VARCHAR(64)"` Avatar string `xorm:"VARCHAR(64)"`
CreatedUnix util.TimeStamp `xorm:"INDEX created"` CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"`
UpdatedUnix util.TimeStamp `xorm:"INDEX updated"` UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"`
} }
// ColorFormat returns a colored string to represent this repo // ColorFormat returns a colored string to represent this repo
@ -971,7 +971,7 @@ func MigrateRepository(doer, u *User, opts MigrateRepoOptions) (*Repository, err
RepoID: repo.ID, RepoID: repo.ID,
Interval: setting.Mirror.DefaultInterval, Interval: setting.Mirror.DefaultInterval,
EnablePrune: true, EnablePrune: true,
NextUpdateUnix: util.TimeStampNow().AddDuration(setting.Mirror.DefaultInterval), NextUpdateUnix: timeutil.TimeStampNow().AddDuration(setting.Mirror.DefaultInterval),
}); err != nil { }); err != nil {
return repo, fmt.Errorf("InsertOne: %v", err) return repo, fmt.Errorf("InsertOne: %v", err)
} }

View File

@ -16,6 +16,7 @@ import (
"code.gitea.io/gitea/modules/process" "code.gitea.io/gitea/modules/process"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/sync" "code.gitea.io/gitea/modules/sync"
"code.gitea.io/gitea/modules/timeutil"
"code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/util"
"github.com/Unknwon/com" "github.com/Unknwon/com"
@ -34,8 +35,8 @@ type Mirror struct {
Interval time.Duration Interval time.Duration
EnablePrune bool `xorm:"NOT NULL DEFAULT true"` EnablePrune bool `xorm:"NOT NULL DEFAULT true"`
UpdatedUnix util.TimeStamp `xorm:"INDEX"` UpdatedUnix timeutil.TimeStamp `xorm:"INDEX"`
NextUpdateUnix util.TimeStamp `xorm:"INDEX"` NextUpdateUnix timeutil.TimeStamp `xorm:"INDEX"`
address string `xorm:"-"` address string `xorm:"-"`
} }
@ -43,8 +44,8 @@ type Mirror struct {
// BeforeInsert will be invoked by XORM before inserting a record // BeforeInsert will be invoked by XORM before inserting a record
func (m *Mirror) BeforeInsert() { func (m *Mirror) BeforeInsert() {
if m != nil { if m != nil {
m.UpdatedUnix = util.TimeStampNow() m.UpdatedUnix = timeutil.TimeStampNow()
m.NextUpdateUnix = util.TimeStampNow() m.NextUpdateUnix = timeutil.TimeStampNow()
} }
} }
@ -64,7 +65,7 @@ func (m *Mirror) AfterLoad(session *xorm.Session) {
// ScheduleNextUpdate calculates and sets next update time. // ScheduleNextUpdate calculates and sets next update time.
func (m *Mirror) ScheduleNextUpdate() { func (m *Mirror) ScheduleNextUpdate() {
if m.Interval != 0 { if m.Interval != 0 {
m.NextUpdateUnix = util.TimeStampNow().AddDuration(m.Interval) m.NextUpdateUnix = timeutil.TimeStampNow().AddDuration(m.Interval)
} else { } else {
m.NextUpdateUnix = 0 m.NextUpdateUnix = 0
} }
@ -277,7 +278,7 @@ func (m *Mirror) runSync() ([]*mirrorSyncResult, bool) {
cache.Remove(m.Repo.GetCommitsCountCacheKey(branches[i].Name, true)) cache.Remove(m.Repo.GetCommitsCountCacheKey(branches[i].Name, true))
} }
m.UpdatedUnix = util.TimeStampNow() m.UpdatedUnix = timeutil.TimeStampNow()
return parseRemoteUpdateOutput(output), true return parseRemoteUpdateOutput(output), true
} }

View File

@ -7,7 +7,7 @@ package models
import ( import (
"encoding/json" "encoding/json"
"code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/timeutil"
"github.com/Unknwon/com" "github.com/Unknwon/com"
"github.com/go-xorm/xorm" "github.com/go-xorm/xorm"
@ -17,10 +17,10 @@ import (
// RepoUnit describes all units of a repository // RepoUnit describes all units of a repository
type RepoUnit struct { type RepoUnit struct {
ID int64 ID int64
RepoID int64 `xorm:"INDEX(s)"` RepoID int64 `xorm:"INDEX(s)"`
Type UnitType `xorm:"INDEX(s)"` Type UnitType `xorm:"INDEX(s)"`
Config core.Conversion `xorm:"TEXT"` Config core.Conversion `xorm:"TEXT"`
CreatedUnix util.TimeStamp `xorm:"INDEX CREATED"` CreatedUnix timeutil.TimeStamp `xorm:"INDEX CREATED"`
} }
// UnitConfig describes common unit config // UnitConfig describes common unit config

View File

@ -8,7 +8,7 @@ import (
"fmt" "fmt"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/timeutil"
"github.com/go-xorm/xorm" "github.com/go-xorm/xorm"
"xorm.io/builder" "xorm.io/builder"
@ -56,8 +56,8 @@ type Review struct {
IssueID int64 `xorm:"index"` IssueID int64 `xorm:"index"`
Content string Content string
CreatedUnix util.TimeStamp `xorm:"INDEX created"` CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"`
UpdatedUnix util.TimeStamp `xorm:"INDEX updated"` UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"`
// CodeComments are the initial code comments of the review // CodeComments are the initial code comments of the review
CodeComments CodeComments `xorm:"-"` CodeComments CodeComments `xorm:"-"`
@ -279,7 +279,7 @@ func UpdateReview(r *Review) error {
type PullReviewersWithType struct { type PullReviewersWithType struct {
User `xorm:"extends"` User `xorm:"extends"`
Type ReviewType Type ReviewType
ReviewUpdatedUnix util.TimeStamp `xorm:"review_updated_unix"` ReviewUpdatedUnix timeutil.TimeStamp `xorm:"review_updated_unix"`
} }
// GetReviewersByPullID gets all reviewers for a pull request with the statuses // GetReviewersByPullID gets all reviewers for a pull request with the statuses

View File

@ -26,7 +26,7 @@ import (
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/process" "code.gitea.io/gitea/modules/process"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/timeutil"
"github.com/Unknwon/com" "github.com/Unknwon/com"
"github.com/go-xorm/xorm" "github.com/go-xorm/xorm"
@ -62,16 +62,16 @@ type PublicKey struct {
Type KeyType `xorm:"NOT NULL DEFAULT 1"` Type KeyType `xorm:"NOT NULL DEFAULT 1"`
LoginSourceID int64 `xorm:"NOT NULL DEFAULT 0"` LoginSourceID int64 `xorm:"NOT NULL DEFAULT 0"`
CreatedUnix util.TimeStamp `xorm:"created"` CreatedUnix timeutil.TimeStamp `xorm:"created"`
UpdatedUnix util.TimeStamp `xorm:"updated"` UpdatedUnix timeutil.TimeStamp `xorm:"updated"`
HasRecentActivity bool `xorm:"-"` HasRecentActivity bool `xorm:"-"`
HasUsed bool `xorm:"-"` HasUsed bool `xorm:"-"`
} }
// AfterLoad is invoked from XORM after setting the values of all fields of this object. // AfterLoad is invoked from XORM after setting the values of all fields of this object.
func (key *PublicKey) AfterLoad() { func (key *PublicKey) AfterLoad() {
key.HasUsed = key.UpdatedUnix > key.CreatedUnix key.HasUsed = key.UpdatedUnix > key.CreatedUnix
key.HasRecentActivity = key.UpdatedUnix.AddDuration(7*24*time.Hour) > util.TimeStampNow() key.HasRecentActivity = key.UpdatedUnix.AddDuration(7*24*time.Hour) > timeutil.TimeStampNow()
} }
// OmitEmail returns content of public key without email address. // OmitEmail returns content of public key without email address.
@ -581,7 +581,7 @@ func UpdatePublicKeyUpdated(id int64) error {
} }
_, err := x.ID(id).Cols("updated_unix").Update(&PublicKey{ _, err := x.ID(id).Cols("updated_unix").Update(&PublicKey{
UpdatedUnix: util.TimeStampNow(), UpdatedUnix: timeutil.TimeStampNow(),
}) })
if err != nil { if err != nil {
return err return err
@ -714,16 +714,16 @@ type DeployKey struct {
Mode AccessMode `xorm:"NOT NULL DEFAULT 1"` Mode AccessMode `xorm:"NOT NULL DEFAULT 1"`
CreatedUnix util.TimeStamp `xorm:"created"` CreatedUnix timeutil.TimeStamp `xorm:"created"`
UpdatedUnix util.TimeStamp `xorm:"updated"` UpdatedUnix timeutil.TimeStamp `xorm:"updated"`
HasRecentActivity bool `xorm:"-"` HasRecentActivity bool `xorm:"-"`
HasUsed bool `xorm:"-"` HasUsed bool `xorm:"-"`
} }
// AfterLoad is invoked from XORM after setting the values of all fields of this object. // AfterLoad is invoked from XORM after setting the values of all fields of this object.
func (key *DeployKey) AfterLoad() { func (key *DeployKey) AfterLoad() {
key.HasUsed = key.UpdatedUnix > key.CreatedUnix key.HasUsed = key.UpdatedUnix > key.CreatedUnix
key.HasRecentActivity = key.UpdatedUnix.AddDuration(7*24*time.Hour) > util.TimeStampNow() key.HasRecentActivity = key.UpdatedUnix.AddDuration(7*24*time.Hour) > timeutil.TimeStampNow()
} }
// GetContent gets associated public key content. // GetContent gets associated public key content.

View File

@ -9,11 +9,11 @@ import (
"crypto/subtle" "crypto/subtle"
"time" "time"
gouuid "github.com/satori/go.uuid"
"code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/base"
"code.gitea.io/gitea/modules/generate" "code.gitea.io/gitea/modules/generate"
"code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/timeutil"
gouuid "github.com/satori/go.uuid"
) )
// AccessToken represents a personal access token. // AccessToken represents a personal access token.
@ -26,16 +26,16 @@ type AccessToken struct {
TokenSalt string TokenSalt string
TokenLastEight string `xorm:"token_last_eight"` TokenLastEight string `xorm:"token_last_eight"`
CreatedUnix util.TimeStamp `xorm:"INDEX created"` CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"`
UpdatedUnix util.TimeStamp `xorm:"INDEX updated"` UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"`
HasRecentActivity bool `xorm:"-"` HasRecentActivity bool `xorm:"-"`
HasUsed bool `xorm:"-"` HasUsed bool `xorm:"-"`
} }
// AfterLoad is invoked from XORM after setting the values of all fields of this object. // AfterLoad is invoked from XORM after setting the values of all fields of this object.
func (t *AccessToken) AfterLoad() { func (t *AccessToken) AfterLoad() {
t.HasUsed = t.UpdatedUnix > t.CreatedUnix t.HasUsed = t.UpdatedUnix > t.CreatedUnix
t.HasRecentActivity = t.UpdatedUnix.AddDuration(7*24*time.Hour) > util.TimeStampNow() t.HasRecentActivity = t.UpdatedUnix.AddDuration(7*24*time.Hour) > timeutil.TimeStampNow()
} }
// NewAccessToken creates new access token. // NewAccessToken creates new access token.

View File

@ -9,7 +9,7 @@ import (
"regexp" "regexp"
"strings" "strings"
"code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/timeutil"
"xorm.io/builder" "xorm.io/builder"
) )
@ -28,8 +28,8 @@ type Topic struct {
ID int64 ID int64
Name string `xorm:"UNIQUE VARCHAR(25)"` Name string `xorm:"UNIQUE VARCHAR(25)"`
RepoCount int RepoCount int
CreatedUnix util.TimeStamp `xorm:"INDEX created"` CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"`
UpdatedUnix util.TimeStamp `xorm:"INDEX updated"` UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"`
} }
// RepoTopic represents associated repositories and topics // RepoTopic represents associated repositories and topics

View File

@ -16,12 +16,12 @@ import (
"fmt" "fmt"
"io" "io"
"github.com/pquerna/otp/totp"
"golang.org/x/crypto/pbkdf2"
"code.gitea.io/gitea/modules/generate" "code.gitea.io/gitea/modules/generate"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/timeutil"
"github.com/pquerna/otp/totp"
"golang.org/x/crypto/pbkdf2"
) )
// TwoFactor represents a two-factor authentication token. // TwoFactor represents a two-factor authentication token.
@ -31,9 +31,9 @@ type TwoFactor struct {
Secret string Secret string
ScratchSalt string ScratchSalt string
ScratchHash string ScratchHash string
LastUsedPasscode string `xorm:"VARCHAR(10)"` LastUsedPasscode string `xorm:"VARCHAR(10)"`
CreatedUnix util.TimeStamp `xorm:"INDEX created"` CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"`
UpdatedUnix util.TimeStamp `xorm:"INDEX updated"` UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"`
} }
// GenerateScratchToken recreates the scratch token the user is using. // GenerateScratchToken recreates the scratch token the user is using.

View File

@ -6,7 +6,7 @@ package models
import ( import (
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/timeutil"
"github.com/tstranex/u2f" "github.com/tstranex/u2f"
) )
@ -17,9 +17,9 @@ type U2FRegistration struct {
Name string Name string
UserID int64 `xorm:"INDEX"` UserID int64 `xorm:"INDEX"`
Raw []byte Raw []byte
Counter uint32 `xorm:"BIGINT"` Counter uint32 `xorm:"BIGINT"`
CreatedUnix util.TimeStamp `xorm:"INDEX created"` CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"`
UpdatedUnix util.TimeStamp `xorm:"INDEX updated"` UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"`
} }
// TableName returns a better table name for U2FRegistration // TableName returns a better table name for U2FRegistration

View File

@ -11,7 +11,7 @@ import (
"time" "time"
"code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/timeutil"
) )
// env keys for git hooks need // env keys for git hooks need
@ -140,7 +140,7 @@ func PushUpdateAddTag(repo *Repository, gitRepo *git.Repository, tagName string)
IsDraft: false, IsDraft: false,
IsPrerelease: false, IsPrerelease: false,
IsTag: true, IsTag: true,
CreatedUnix: util.TimeStamp(createdAt.Unix()), CreatedUnix: timeutil.TimeStamp(createdAt.Unix()),
} }
if author != nil { if author != nil {
rel.PublisherID = author.ID rel.PublisherID = author.ID
@ -151,7 +151,7 @@ func PushUpdateAddTag(repo *Repository, gitRepo *git.Repository, tagName string)
} }
} else { } else {
rel.Sha1 = commit.ID.String() rel.Sha1 = commit.ID.String()
rel.CreatedUnix = util.TimeStamp(createdAt.Unix()) rel.CreatedUnix = timeutil.TimeStamp(createdAt.Unix())
rel.NumCommits = commitsCount rel.NumCommits = commitsCount
rel.IsDraft = false rel.IsDraft = false
if rel.IsTag && author != nil { if rel.IsTag && author != nil {

View File

@ -29,6 +29,7 @@ import (
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/structs"
api "code.gitea.io/gitea/modules/structs" api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/timeutil"
"code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/util"
"github.com/Unknwon/com" "github.com/Unknwon/com"
@ -110,9 +111,9 @@ type User struct {
Language string `xorm:"VARCHAR(5)"` Language string `xorm:"VARCHAR(5)"`
Description string Description string
CreatedUnix util.TimeStamp `xorm:"INDEX created"` CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"`
UpdatedUnix util.TimeStamp `xorm:"INDEX updated"` UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"`
LastLoginUnix util.TimeStamp `xorm:"INDEX"` LastLoginUnix timeutil.TimeStamp `xorm:"INDEX"`
// Remember visibility choice for convenience, true for private // Remember visibility choice for convenience, true for private
LastRepoVisibility bool LastRepoVisibility bool
@ -190,7 +191,7 @@ func (u *User) AfterLoad() {
// SetLastLogin set time to last login // SetLastLogin set time to last login
func (u *User) SetLastLogin() { func (u *User) SetLastLogin() {
u.LastLoginUnix = util.TimeStampNow() u.LastLoginUnix = timeutil.TimeStampNow()
} }
// UpdateDiffViewStyle updates the users diff view style // UpdateDiffViewStyle updates the users diff view style

View File

@ -6,13 +6,13 @@ package models
import ( import (
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/timeutil"
) )
// UserHeatmapData represents the data needed to create a heatmap // UserHeatmapData represents the data needed to create a heatmap
type UserHeatmapData struct { type UserHeatmapData struct {
Timestamp util.TimeStamp `json:"timestamp"` Timestamp timeutil.TimeStamp `json:"timestamp"`
Contributions int64 `json:"contributions"` Contributions int64 `json:"contributions"`
} }
// GetUserHeatmapDataByUser returns an array of UserHeatmapData // GetUserHeatmapDataByUser returns an array of UserHeatmapData
@ -35,7 +35,7 @@ func GetUserHeatmapDataByUser(user *User) ([]*UserHeatmapData, error) {
sess := x.Select(groupBy+" AS timestamp, count(user_id) as contributions"). sess := x.Select(groupBy+" AS timestamp, count(user_id) as contributions").
Table("action"). Table("action").
Where("user_id = ?", user.ID). Where("user_id = ?", user.ID).
And("created_unix > ?", (util.TimeStampNow() - 31536000)) And("created_unix > ?", (timeutil.TimeStampNow() - 31536000))
// * Heatmaps for individual users only include actions that the user themself // * Heatmaps for individual users only include actions that the user themself
// did. // did.

View File

@ -23,7 +23,8 @@ import (
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
api "code.gitea.io/gitea/modules/structs" api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/sync" "code.gitea.io/gitea/modules/sync"
"code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/timeutil"
"github.com/Unknwon/com" "github.com/Unknwon/com"
gouuid "github.com/satori/go.uuid" gouuid "github.com/satori/go.uuid"
) )
@ -118,8 +119,8 @@ type Webhook struct {
Meta string `xorm:"TEXT"` // store hook-specific attributes Meta string `xorm:"TEXT"` // store hook-specific attributes
LastStatus HookStatus // Last delivery status LastStatus HookStatus // Last delivery status
CreatedUnix util.TimeStamp `xorm:"INDEX created"` CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"`
UpdatedUnix util.TimeStamp `xorm:"INDEX updated"` UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"`
} }
// AfterLoad updates the webhook object upon setting a column // AfterLoad updates the webhook object upon setting a column

View File

@ -20,7 +20,7 @@ import (
"code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/base"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/timeutil"
"code.gitea.io/gitea/modules/validation" "code.gitea.io/gitea/modules/validation"
) )
@ -68,7 +68,7 @@ func SignedInID(ctx *macaron.Context, sess session.Store) int64 {
} }
return 0 return 0
} }
t.UpdatedUnix = util.TimeStampNow() t.UpdatedUnix = timeutil.TimeStampNow()
if err = models.UpdateAccessToken(t); err != nil { if err = models.UpdateAccessToken(t); err != nil {
log.Error("UpdateAccessToken: %v", err) log.Error("UpdateAccessToken: %v", err)
} }
@ -210,7 +210,7 @@ func SignedInUser(ctx *macaron.Context, sess session.Store) (*models.User, bool)
return nil, false return nil, false
} }
} }
token.UpdatedUnix = util.TimeStampNow() token.UpdatedUnix = timeutil.TimeStampNow()
if err = models.UpdateAccessToken(token); err != nil { if err = models.UpdateAccessToken(token); err != nil {
log.Error("UpdateAccessToken: %v", err) log.Error("UpdateAccessToken: %v", err)
} }

View File

@ -12,7 +12,6 @@ import (
"encoding/base64" "encoding/base64"
"encoding/hex" "encoding/hex"
"fmt" "fmt"
"html/template"
"io" "io"
"math" "math"
"net/http" "net/http"
@ -29,10 +28,8 @@ import (
"code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/util"
"github.com/Unknwon/com" "github.com/Unknwon/com"
"github.com/Unknwon/i18n"
) )
// EncodeMD5 encodes string to md5 hex value. // EncodeMD5 encodes string to md5 hex value.
@ -217,154 +214,6 @@ func AvatarLink(email string) string {
return SizedAvatarLink(email, DefaultAvatarSize) return SizedAvatarLink(email, DefaultAvatarSize)
} }
// Seconds-based time units
const (
Minute = 60
Hour = 60 * Minute
Day = 24 * Hour
Week = 7 * Day
Month = 30 * Day
Year = 12 * Month
)
func computeTimeDiff(diff int64, lang string) (int64, string) {
diffStr := ""
switch {
case diff <= 0:
diff = 0
diffStr = i18n.Tr(lang, "tool.now")
case diff < 2:
diff = 0
diffStr = i18n.Tr(lang, "tool.1s")
case diff < 1*Minute:
diffStr = i18n.Tr(lang, "tool.seconds", diff)
diff = 0
case diff < 2*Minute:
diff -= 1 * Minute
diffStr = i18n.Tr(lang, "tool.1m")
case diff < 1*Hour:
diffStr = i18n.Tr(lang, "tool.minutes", diff/Minute)
diff -= diff / Minute * Minute
case diff < 2*Hour:
diff -= 1 * Hour
diffStr = i18n.Tr(lang, "tool.1h")
case diff < 1*Day:
diffStr = i18n.Tr(lang, "tool.hours", diff/Hour)
diff -= diff / Hour * Hour
case diff < 2*Day:
diff -= 1 * Day
diffStr = i18n.Tr(lang, "tool.1d")
case diff < 1*Week:
diffStr = i18n.Tr(lang, "tool.days", diff/Day)
diff -= diff / Day * Day
case diff < 2*Week:
diff -= 1 * Week
diffStr = i18n.Tr(lang, "tool.1w")
case diff < 1*Month:
diffStr = i18n.Tr(lang, "tool.weeks", diff/Week)
diff -= diff / Week * Week
case diff < 2*Month:
diff -= 1 * Month
diffStr = i18n.Tr(lang, "tool.1mon")
case diff < 1*Year:
diffStr = i18n.Tr(lang, "tool.months", diff/Month)
diff -= diff / Month * Month
case diff < 2*Year:
diff -= 1 * Year
diffStr = i18n.Tr(lang, "tool.1y")
default:
diffStr = i18n.Tr(lang, "tool.years", diff/Year)
diff -= (diff / Year) * Year
}
return diff, diffStr
}
// MinutesToFriendly returns a user friendly string with number of minutes
// converted to hours and minutes.
func MinutesToFriendly(minutes int, lang string) string {
duration := time.Duration(minutes) * time.Minute
return TimeSincePro(time.Now().Add(-duration), lang)
}
// TimeSincePro calculates the time interval and generate full user-friendly string.
func TimeSincePro(then time.Time, lang string) string {
return timeSincePro(then, time.Now(), lang)
}
func timeSincePro(then, now time.Time, lang string) string {
diff := now.Unix() - then.Unix()
if then.After(now) {
return i18n.Tr(lang, "tool.future")
}
if diff == 0 {
return i18n.Tr(lang, "tool.now")
}
var timeStr, diffStr string
for {
if diff == 0 {
break
}
diff, diffStr = computeTimeDiff(diff, lang)
timeStr += ", " + diffStr
}
return strings.TrimPrefix(timeStr, ", ")
}
func timeSince(then, now time.Time, lang string) string {
return timeSinceUnix(then.Unix(), now.Unix(), lang)
}
func timeSinceUnix(then, now int64, lang string) string {
lbl := "tool.ago"
diff := now - then
if then > now {
lbl = "tool.from_now"
diff = then - now
}
if diff <= 0 {
return i18n.Tr(lang, "tool.now")
}
_, diffStr := computeTimeDiff(diff, lang)
return i18n.Tr(lang, lbl, diffStr)
}
// RawTimeSince retrieves i18n key of time since t
func RawTimeSince(t time.Time, lang string) string {
return timeSince(t, time.Now(), lang)
}
// TimeSince calculates the time interval and generate user-friendly string.
func TimeSince(then time.Time, lang string) template.HTML {
return htmlTimeSince(then, time.Now(), lang)
}
func htmlTimeSince(then, now time.Time, lang string) template.HTML {
return template.HTML(fmt.Sprintf(`<span class="time-since" title="%s">%s</span>`,
then.Format(setting.TimeFormat),
timeSince(then, now, lang)))
}
// TimeSinceUnix calculates the time interval and generate user-friendly string.
func TimeSinceUnix(then util.TimeStamp, lang string) template.HTML {
return htmlTimeSinceUnix(then, util.TimeStamp(time.Now().Unix()), lang)
}
func htmlTimeSinceUnix(then, now util.TimeStamp, lang string) template.HTML {
return template.HTML(fmt.Sprintf(`<span class="time-since" title="%s">%s</span>`,
then.Format(setting.TimeFormat),
timeSinceUnix(int64(then), int64(now), lang)))
}
// Storage space size types // Storage space size types
const ( const (
Byte = 1 Byte = 1

View File

@ -2,43 +2,13 @@ package base
import ( import (
"net/url" "net/url"
"os"
"testing" "testing"
"time"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
"github.com/Unknwon/i18n"
macaroni18n "github.com/go-macaron/i18n"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
var BaseDate time.Time
// time durations
const (
DayDur = 24 * time.Hour
WeekDur = 7 * DayDur
MonthDur = 30 * DayDur
YearDur = 12 * MonthDur
)
func TestMain(m *testing.M) {
// setup
macaroni18n.I18n(macaroni18n.Options{
Directory: "../../options/locale/",
DefaultLang: "en-US",
Langs: []string{"en-US"},
Names: []string{"english"},
})
BaseDate = time.Date(2000, time.January, 1, 0, 0, 0, 0, time.UTC)
// run the tests
retVal := m.Run()
os.Exit(retVal)
}
func TestEncodeMD5(t *testing.T) { func TestEncodeMD5(t *testing.T) {
assert.Equal(t, assert.Equal(t,
"3858f62230ac3c915f300c664312c63f", "3858f62230ac3c915f300c664312c63f",
@ -131,125 +101,6 @@ func TestAvatarLink(t *testing.T) {
) )
} }
func TestComputeTimeDiff(t *testing.T) {
// test that for each offset in offsets,
// computeTimeDiff(base + offset) == (offset, str)
test := func(base int64, str string, offsets ...int64) {
for _, offset := range offsets {
diff, diffStr := computeTimeDiff(base+offset, "en")
assert.Equal(t, offset, diff)
assert.Equal(t, str, diffStr)
}
}
test(0, "now", 0)
test(1, "1 second", 0)
test(2, "2 seconds", 0)
test(Minute, "1 minute", 0, 1, 30, Minute-1)
test(2*Minute, "2 minutes", 0, Minute-1)
test(Hour, "1 hour", 0, 1, Hour-1)
test(5*Hour, "5 hours", 0, Hour-1)
test(Day, "1 day", 0, 1, Day-1)
test(5*Day, "5 days", 0, Day-1)
test(Week, "1 week", 0, 1, Week-1)
test(3*Week, "3 weeks", 0, 4*Day+25000)
test(Month, "1 month", 0, 1, Month-1)
test(10*Month, "10 months", 0, Month-1)
test(Year, "1 year", 0, Year-1)
test(3*Year, "3 years", 0, Year-1)
}
func TestMinutesToFriendly(t *testing.T) {
// test that a number of minutes yields the expected string
test := func(expected string, minutes int) {
actual := MinutesToFriendly(minutes, "en")
assert.Equal(t, expected, actual)
}
test("1 minute", 1)
test("2 minutes", 2)
test("1 hour", 60)
test("1 hour, 1 minute", 61)
test("1 hour, 2 minutes", 62)
test("2 hours", 120)
}
func TestTimeSince(t *testing.T) {
assert.Equal(t, "now", timeSince(BaseDate, BaseDate, "en"))
// test that each diff in `diffs` yields the expected string
test := func(expected string, diffs ...time.Duration) {
for _, diff := range diffs {
actual := timeSince(BaseDate, BaseDate.Add(diff), "en")
assert.Equal(t, i18n.Tr("en", "tool.ago", expected), actual)
actual = timeSince(BaseDate.Add(diff), BaseDate, "en")
assert.Equal(t, i18n.Tr("en", "tool.from_now", expected), actual)
}
}
test("1 second", time.Second, time.Second+50*time.Millisecond)
test("2 seconds", 2*time.Second, 2*time.Second+50*time.Millisecond)
test("1 minute", time.Minute, time.Minute+30*time.Second)
test("2 minutes", 2*time.Minute, 2*time.Minute+30*time.Second)
test("1 hour", time.Hour, time.Hour+30*time.Minute)
test("2 hours", 2*time.Hour, 2*time.Hour+30*time.Minute)
test("1 day", DayDur, DayDur+12*time.Hour)
test("2 days", 2*DayDur, 2*DayDur+12*time.Hour)
test("1 week", WeekDur, WeekDur+3*DayDur)
test("2 weeks", 2*WeekDur, 2*WeekDur+3*DayDur)
test("1 month", MonthDur, MonthDur+15*DayDur)
test("2 months", 2*MonthDur, 2*MonthDur+15*DayDur)
test("1 year", YearDur, YearDur+6*MonthDur)
test("2 years", 2*YearDur, 2*YearDur+6*MonthDur)
}
func TestTimeSincePro(t *testing.T) {
assert.Equal(t, "now", timeSincePro(BaseDate, BaseDate, "en"))
// test that a difference of `diff` yields the expected string
test := func(expected string, diff time.Duration) {
actual := timeSincePro(BaseDate, BaseDate.Add(diff), "en")
assert.Equal(t, expected, actual)
assert.Equal(t, "future", timeSincePro(BaseDate.Add(diff), BaseDate, "en"))
}
test("1 second", time.Second)
test("2 seconds", 2*time.Second)
test("1 minute", time.Minute)
test("1 minute, 1 second", time.Minute+time.Second)
test("1 minute, 59 seconds", time.Minute+59*time.Second)
test("2 minutes", 2*time.Minute)
test("1 hour", time.Hour)
test("1 hour, 1 second", time.Hour+time.Second)
test("1 hour, 59 minutes, 59 seconds", time.Hour+59*time.Minute+59*time.Second)
test("2 hours", 2*time.Hour)
test("1 day", DayDur)
test("1 day, 23 hours, 59 minutes, 59 seconds",
DayDur+23*time.Hour+59*time.Minute+59*time.Second)
test("2 days", 2*DayDur)
test("1 week", WeekDur)
test("2 weeks", 2*WeekDur)
test("1 month", MonthDur)
test("3 months", 3*MonthDur)
test("1 year", YearDur)
test("2 years, 3 months, 1 week, 2 days, 4 hours, 12 minutes, 17 seconds",
2*YearDur+3*MonthDur+WeekDur+2*DayDur+4*time.Hour+
12*time.Minute+17*time.Second)
}
func TestHtmlTimeSince(t *testing.T) {
setting.TimeFormat = time.UnixDate
// test that `diff` yields a result containing `expected`
test := func(expected string, diff time.Duration) {
actual := htmlTimeSince(BaseDate, BaseDate.Add(diff), "en")
assert.Contains(t, actual, `title="Sat Jan 1 00:00:00 UTC 2000"`)
assert.Contains(t, actual, expected)
}
test("1 second", time.Second)
test("3 minutes", 3*time.Minute+5*time.Second)
test("1 day", DayDur+18*time.Hour)
test("1 week", WeekDur+6*DayDur)
test("3 months", 3*MonthDur+3*WeekDur)
test("2 years", 2*YearDur)
test("3 years", 3*YearDur+11*MonthDur+4*WeekDur)
}
func TestFileSize(t *testing.T) { func TestFileSize(t *testing.T) {
var size int64 = 512 var size int64 = 512
assert.Equal(t, "512B", FileSize(size)) assert.Equal(t, "512B", FileSize(size))

View File

@ -21,7 +21,7 @@ import (
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/migrations/base" "code.gitea.io/gitea/modules/migrations/base"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/timeutil"
gouuid "github.com/satori/go.uuid" gouuid "github.com/satori/go.uuid"
) )
@ -106,12 +106,12 @@ func (g *GiteaLocalUploader) CreateTopics(topics ...string) error {
func (g *GiteaLocalUploader) CreateMilestones(milestones ...*base.Milestone) error { func (g *GiteaLocalUploader) CreateMilestones(milestones ...*base.Milestone) error {
var mss = make([]*models.Milestone, 0, len(milestones)) var mss = make([]*models.Milestone, 0, len(milestones))
for _, milestone := range milestones { for _, milestone := range milestones {
var deadline util.TimeStamp var deadline timeutil.TimeStamp
if milestone.Deadline != nil { if milestone.Deadline != nil {
deadline = util.TimeStamp(milestone.Deadline.Unix()) deadline = timeutil.TimeStamp(milestone.Deadline.Unix())
} }
if deadline == 0 { if deadline == 0 {
deadline = util.TimeStamp(time.Date(9999, 1, 1, 0, 0, 0, 0, setting.UILocation).Unix()) deadline = timeutil.TimeStamp(time.Date(9999, 1, 1, 0, 0, 0, 0, setting.DefaultUILocation).Unix())
} }
var ms = models.Milestone{ var ms = models.Milestone{
RepoID: g.repo.ID, RepoID: g.repo.ID,
@ -121,7 +121,7 @@ func (g *GiteaLocalUploader) CreateMilestones(milestones ...*base.Milestone) err
DeadlineUnix: deadline, DeadlineUnix: deadline,
} }
if ms.IsClosed && milestone.Closed != nil { if ms.IsClosed && milestone.Closed != nil {
ms.ClosedDateUnix = util.TimeStamp(milestone.Closed.Unix()) ms.ClosedDateUnix = timeutil.TimeStamp(milestone.Closed.Unix())
} }
mss = append(mss, &ms) mss = append(mss, &ms)
} }
@ -175,7 +175,7 @@ func (g *GiteaLocalUploader) CreateReleases(releases ...*base.Release) error {
IsDraft: release.Draft, IsDraft: release.Draft,
IsPrerelease: release.Prerelease, IsPrerelease: release.Prerelease,
IsTag: false, IsTag: false,
CreatedUnix: util.TimeStamp(release.Created.Unix()), CreatedUnix: timeutil.TimeStamp(release.Created.Unix()),
} }
// calc NumCommits // calc NumCommits
@ -194,7 +194,7 @@ func (g *GiteaLocalUploader) CreateReleases(releases ...*base.Release) error {
Name: asset.Name, Name: asset.Name,
DownloadCount: int64(*asset.DownloadCount), DownloadCount: int64(*asset.DownloadCount),
Size: int64(*asset.Size), Size: int64(*asset.Size),
CreatedUnix: util.TimeStamp(asset.Created.Unix()), CreatedUnix: timeutil.TimeStamp(asset.Created.Unix()),
} }
// download attachment // download attachment
@ -265,10 +265,10 @@ func (g *GiteaLocalUploader) CreateIssues(issues ...*base.Issue) error {
IsLocked: issue.IsLocked, IsLocked: issue.IsLocked,
MilestoneID: milestoneID, MilestoneID: milestoneID,
Labels: labels, Labels: labels,
CreatedUnix: util.TimeStamp(issue.Created.Unix()), CreatedUnix: timeutil.TimeStamp(issue.Created.Unix()),
} }
if issue.Closed != nil { if issue.Closed != nil {
is.ClosedUnix = util.TimeStamp(issue.Closed.Unix()) is.ClosedUnix = timeutil.TimeStamp(issue.Closed.Unix())
} }
// TODO: add reactions // TODO: add reactions
iss = append(iss, &is) iss = append(iss, &is)
@ -307,7 +307,7 @@ func (g *GiteaLocalUploader) CreateComments(comments ...*base.Comment) error {
OriginalAuthor: comment.PosterName, OriginalAuthor: comment.PosterName,
OriginalAuthorID: comment.PosterID, OriginalAuthorID: comment.PosterID,
Content: comment.Content, Content: comment.Content,
CreatedUnix: util.TimeStamp(comment.Created.Unix()), CreatedUnix: timeutil.TimeStamp(comment.Created.Unix()),
}) })
// TODO: Reactions // TODO: Reactions
@ -453,15 +453,15 @@ func (g *GiteaLocalUploader) newPullRequest(pr *base.PullRequest) (*models.PullR
IsClosed: pr.State == "closed", IsClosed: pr.State == "closed",
IsLocked: pr.IsLocked, IsLocked: pr.IsLocked,
Labels: labels, Labels: labels,
CreatedUnix: util.TimeStamp(pr.Created.Unix()), CreatedUnix: timeutil.TimeStamp(pr.Created.Unix()),
}, },
} }
if pullRequest.Issue.IsClosed && pr.Closed != nil { if pullRequest.Issue.IsClosed && pr.Closed != nil {
pullRequest.Issue.ClosedUnix = util.TimeStamp(pr.Closed.Unix()) pullRequest.Issue.ClosedUnix = timeutil.TimeStamp(pr.Closed.Unix())
} }
if pullRequest.HasMerged && pr.MergedTime != nil { if pullRequest.HasMerged && pr.MergedTime != nil {
pullRequest.MergedUnix = util.TimeStamp(pr.MergedTime.Unix()) pullRequest.MergedUnix = timeutil.TimeStamp(pr.MergedTime.Unix())
pullRequest.MergedCommitID = pr.MergeCommitSHA pullRequest.MergedCommitID = pr.MergeCommitSHA
pullRequest.MergerID = g.doer.ID pullRequest.MergerID = g.doer.ID
} }

View File

@ -21,7 +21,7 @@ import (
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
api "code.gitea.io/gitea/modules/structs" api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/timeutil"
) )
// Merge merges pull request to base repository. // Merge merges pull request to base repository.
@ -258,7 +258,7 @@ func Merge(pr *models.PullRequest, doer *models.User, baseGitRepo *git.Repositor
return fmt.Errorf("GetBranchCommit: %v", err) return fmt.Errorf("GetBranchCommit: %v", err)
} }
pr.MergedUnix = util.TimeStampNow() pr.MergedUnix = timeutil.TimeStampNow()
pr.Merger = doer pr.Merger = doer
pr.MergerID = doer.ID pr.MergerID = doer.ID

View File

@ -278,6 +278,8 @@ var (
// Time settings // Time settings
TimeFormat string TimeFormat string
// UILocation is the location on the UI, so that we can display the time on UI.
DefaultUILocation = time.Local
CSRFCookieName = "_csrf" CSRFCookieName = "_csrf"
CSRFCookieHTTPOnly = true CSRFCookieHTTPOnly = true
@ -356,10 +358,6 @@ var (
HasRobotsTxt bool HasRobotsTxt bool
InternalToken string // internal access token InternalToken string // internal access token
IterateBufferSize int IterateBufferSize int
// UILocation is the location on the UI, so that we can display the time on UI.
// Currently only show the default time.Local, it could be added to app.ini after UI is ready
UILocation = time.Local
) )
// DateLang transforms standard language locale name to corresponding value in datetime plugin. // DateLang transforms standard language locale name to corresponding value in datetime plugin.
@ -792,32 +790,47 @@ func NewContext() {
AttachmentMaxFiles = sec.Key("MAX_FILES").MustInt(5) AttachmentMaxFiles = sec.Key("MAX_FILES").MustInt(5)
AttachmentEnabled = sec.Key("ENABLED").MustBool(true) AttachmentEnabled = sec.Key("ENABLED").MustBool(true)
TimeFormatKey := Cfg.Section("time").Key("FORMAT").MustString("RFC1123") timeFormatKey := Cfg.Section("time").Key("FORMAT").MustString("")
TimeFormat = map[string]string{ if timeFormatKey != "" {
"ANSIC": time.ANSIC, TimeFormat = map[string]string{
"UnixDate": time.UnixDate, "ANSIC": time.ANSIC,
"RubyDate": time.RubyDate, "UnixDate": time.UnixDate,
"RFC822": time.RFC822, "RubyDate": time.RubyDate,
"RFC822Z": time.RFC822Z, "RFC822": time.RFC822,
"RFC850": time.RFC850, "RFC822Z": time.RFC822Z,
"RFC1123": time.RFC1123, "RFC850": time.RFC850,
"RFC1123Z": time.RFC1123Z, "RFC1123": time.RFC1123,
"RFC3339": time.RFC3339, "RFC1123Z": time.RFC1123Z,
"RFC3339Nano": time.RFC3339Nano, "RFC3339": time.RFC3339,
"Kitchen": time.Kitchen, "RFC3339Nano": time.RFC3339Nano,
"Stamp": time.Stamp, "Kitchen": time.Kitchen,
"StampMilli": time.StampMilli, "Stamp": time.Stamp,
"StampMicro": time.StampMicro, "StampMilli": time.StampMilli,
"StampNano": time.StampNano, "StampMicro": time.StampMicro,
}[TimeFormatKey] "StampNano": time.StampNano,
// When the TimeFormatKey does not exist in the previous map e.g.'2006-01-02 15:04:05' }[timeFormatKey]
if len(TimeFormat) == 0 { // When the TimeFormatKey does not exist in the previous map e.g.'2006-01-02 15:04:05'
TimeFormat = TimeFormatKey if len(TimeFormat) == 0 {
TestTimeFormat, _ := time.Parse(TimeFormat, TimeFormat) TimeFormat = timeFormatKey
if TestTimeFormat.Format(time.RFC3339) != "2006-01-02T15:04:05Z" { TestTimeFormat, _ := time.Parse(TimeFormat, TimeFormat)
log.Fatal("Can't create time properly, please check your time format has 2006, 01, 02, 15, 04 and 05") if TestTimeFormat.Format(time.RFC3339) != "2006-01-02T15:04:05Z" {
log.Fatal("Can't create time properly, please check your time format has 2006, 01, 02, 15, 04 and 05")
}
log.Trace("Custom TimeFormat: %s", TimeFormat)
} }
log.Trace("Custom TimeFormat: %s", TimeFormat) }
zone := Cfg.Section("time").Key("DEFAULT_UI_LOCATION").String()
if zone != "" {
DefaultUILocation, err = time.LoadLocation(zone)
if err != nil {
log.Fatal("Load time zone failed: %v", err)
} else {
log.Info("Default UI Location is %v", zone)
}
}
if DefaultUILocation == nil {
DefaultUILocation = time.Local
} }
RunUser = Cfg.Section("").Key("RUN_USER").MustString(user.CurrentUsername()) RunUser = Cfg.Section("").Key("RUN_USER").MustString(user.CurrentUsername())

View File

@ -20,13 +20,13 @@ import (
"strings" "strings"
"time" "time"
"code.gitea.io/gitea/modules/util"
"code.gitea.io/gitea/models" "code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/base"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/markup" "code.gitea.io/gitea/modules/markup"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/timeutil"
"code.gitea.io/gitea/modules/util"
"gopkg.in/editorconfig/editorconfig-core-go.v1" "gopkg.in/editorconfig/editorconfig-core-go.v1"
) )
@ -74,9 +74,9 @@ func NewFuncMap() []template.FuncMap {
"Safe": Safe, "Safe": Safe,
"SafeJS": SafeJS, "SafeJS": SafeJS,
"Str2html": Str2html, "Str2html": Str2html,
"TimeSince": base.TimeSince, "TimeSince": timeutil.TimeSince,
"TimeSinceUnix": base.TimeSinceUnix, "TimeSinceUnix": timeutil.TimeSinceUnix,
"RawTimeSince": base.RawTimeSince, "RawTimeSince": timeutil.RawTimeSince,
"FileSize": base.FileSize, "FileSize": base.FileSize,
"Subtract": base.Subtract, "Subtract": base.Subtract,
"EntryIcon": base.EntryIcon, "EntryIcon": base.EntryIcon,

View File

@ -0,0 +1,36 @@
// Copyright 2019 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package timeutil
import (
"time"
"code.gitea.io/gitea/modules/setting"
)
var (
langTimeFormats = map[string]string{
"zh-CN": "2006年01月02日 15时04分05秒",
"en-US": time.RFC1123,
"lv-LV": "02.01.2006. 15:04:05",
}
)
// GetLangTimeFormat represents the default time format for the language
func GetLangTimeFormat(lang string) string {
return langTimeFormats[lang]
}
// GetTimeFormat represents the
func GetTimeFormat(lang string) string {
if setting.TimeFormat == "" {
format := GetLangTimeFormat(lang)
if format == "" {
format = time.RFC1123
}
return format
}
return setting.TimeFormat
}

164
modules/timeutil/since.go Normal file
View File

@ -0,0 +1,164 @@
// Copyright 2019 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package timeutil
import (
"fmt"
"html/template"
"strings"
"time"
"code.gitea.io/gitea/modules/setting"
"github.com/Unknwon/i18n"
)
// Seconds-based time units
const (
Minute = 60
Hour = 60 * Minute
Day = 24 * Hour
Week = 7 * Day
Month = 30 * Day
Year = 12 * Month
)
func computeTimeDiff(diff int64, lang string) (int64, string) {
diffStr := ""
switch {
case diff <= 0:
diff = 0
diffStr = i18n.Tr(lang, "tool.now")
case diff < 2:
diff = 0
diffStr = i18n.Tr(lang, "tool.1s")
case diff < 1*Minute:
diffStr = i18n.Tr(lang, "tool.seconds", diff)
diff = 0
case diff < 2*Minute:
diff -= 1 * Minute
diffStr = i18n.Tr(lang, "tool.1m")
case diff < 1*Hour:
diffStr = i18n.Tr(lang, "tool.minutes", diff/Minute)
diff -= diff / Minute * Minute
case diff < 2*Hour:
diff -= 1 * Hour
diffStr = i18n.Tr(lang, "tool.1h")
case diff < 1*Day:
diffStr = i18n.Tr(lang, "tool.hours", diff/Hour)
diff -= diff / Hour * Hour
case diff < 2*Day:
diff -= 1 * Day
diffStr = i18n.Tr(lang, "tool.1d")
case diff < 1*Week:
diffStr = i18n.Tr(lang, "tool.days", diff/Day)
diff -= diff / Day * Day
case diff < 2*Week:
diff -= 1 * Week
diffStr = i18n.Tr(lang, "tool.1w")
case diff < 1*Month:
diffStr = i18n.Tr(lang, "tool.weeks", diff/Week)
diff -= diff / Week * Week
case diff < 2*Month:
diff -= 1 * Month
diffStr = i18n.Tr(lang, "tool.1mon")
case diff < 1*Year:
diffStr = i18n.Tr(lang, "tool.months", diff/Month)
diff -= diff / Month * Month
case diff < 2*Year:
diff -= 1 * Year
diffStr = i18n.Tr(lang, "tool.1y")
default:
diffStr = i18n.Tr(lang, "tool.years", diff/Year)
diff -= (diff / Year) * Year
}
return diff, diffStr
}
// MinutesToFriendly returns a user friendly string with number of minutes
// converted to hours and minutes.
func MinutesToFriendly(minutes int, lang string) string {
duration := time.Duration(minutes) * time.Minute
return TimeSincePro(time.Now().Add(-duration), lang)
}
// TimeSincePro calculates the time interval and generate full user-friendly string.
func TimeSincePro(then time.Time, lang string) string {
return timeSincePro(then, time.Now(), lang)
}
func timeSincePro(then, now time.Time, lang string) string {
diff := now.Unix() - then.Unix()
if then.After(now) {
return i18n.Tr(lang, "tool.future")
}
if diff == 0 {
return i18n.Tr(lang, "tool.now")
}
var timeStr, diffStr string
for {
if diff == 0 {
break
}
diff, diffStr = computeTimeDiff(diff, lang)
timeStr += ", " + diffStr
}
return strings.TrimPrefix(timeStr, ", ")
}
func timeSince(then, now time.Time, lang string) string {
return timeSinceUnix(then.Unix(), now.Unix(), lang)
}
func timeSinceUnix(then, now int64, lang string) string {
lbl := "tool.ago"
diff := now - then
if then > now {
lbl = "tool.from_now"
diff = then - now
}
if diff <= 0 {
return i18n.Tr(lang, "tool.now")
}
_, diffStr := computeTimeDiff(diff, lang)
return i18n.Tr(lang, lbl, diffStr)
}
// RawTimeSince retrieves i18n key of time since t
func RawTimeSince(t time.Time, lang string) string {
return timeSince(t, time.Now(), lang)
}
// TimeSince calculates the time interval and generate user-friendly string.
func TimeSince(then time.Time, lang string) template.HTML {
return htmlTimeSince(then, time.Now(), lang)
}
func htmlTimeSince(then, now time.Time, lang string) template.HTML {
return template.HTML(fmt.Sprintf(`<span class="time-since" title="%s">%s</span>`,
then.In(setting.DefaultUILocation).Format(GetTimeFormat(lang)),
timeSince(then, now, lang)))
}
// TimeSinceUnix calculates the time interval and generate user-friendly string.
func TimeSinceUnix(then TimeStamp, lang string) template.HTML {
return htmlTimeSinceUnix(then, TimeStamp(time.Now().Unix()), lang)
}
func htmlTimeSinceUnix(then, now TimeStamp, lang string) template.HTML {
return template.HTML(fmt.Sprintf(`<span class="time-since" title="%s">%s</span>`,
then.FormatInLocation(GetTimeFormat(lang), setting.DefaultUILocation),
timeSinceUnix(int64(then), int64(now), lang)))
}

View File

@ -0,0 +1,163 @@
// Copyright 2019 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package timeutil
import (
"os"
"testing"
"time"
"code.gitea.io/gitea/modules/setting"
"github.com/Unknwon/i18n"
macaroni18n "github.com/go-macaron/i18n"
"github.com/stretchr/testify/assert"
)
var BaseDate time.Time
// time durations
const (
DayDur = 24 * time.Hour
WeekDur = 7 * DayDur
MonthDur = 30 * DayDur
YearDur = 12 * MonthDur
)
func TestMain(m *testing.M) {
// setup
macaroni18n.I18n(macaroni18n.Options{
Directory: "../../options/locale/",
DefaultLang: "en-US",
Langs: []string{"en-US"},
Names: []string{"english"},
})
BaseDate = time.Date(2000, time.January, 1, 0, 0, 0, 0, time.UTC)
// run the tests
retVal := m.Run()
os.Exit(retVal)
}
func TestTimeSince(t *testing.T) {
assert.Equal(t, "now", timeSince(BaseDate, BaseDate, "en"))
// test that each diff in `diffs` yields the expected string
test := func(expected string, diffs ...time.Duration) {
for _, diff := range diffs {
actual := timeSince(BaseDate, BaseDate.Add(diff), "en")
assert.Equal(t, i18n.Tr("en", "tool.ago", expected), actual)
actual = timeSince(BaseDate.Add(diff), BaseDate, "en")
assert.Equal(t, i18n.Tr("en", "tool.from_now", expected), actual)
}
}
test("1 second", time.Second, time.Second+50*time.Millisecond)
test("2 seconds", 2*time.Second, 2*time.Second+50*time.Millisecond)
test("1 minute", time.Minute, time.Minute+30*time.Second)
test("2 minutes", 2*time.Minute, 2*time.Minute+30*time.Second)
test("1 hour", time.Hour, time.Hour+30*time.Minute)
test("2 hours", 2*time.Hour, 2*time.Hour+30*time.Minute)
test("1 day", DayDur, DayDur+12*time.Hour)
test("2 days", 2*DayDur, 2*DayDur+12*time.Hour)
test("1 week", WeekDur, WeekDur+3*DayDur)
test("2 weeks", 2*WeekDur, 2*WeekDur+3*DayDur)
test("1 month", MonthDur, MonthDur+15*DayDur)
test("2 months", 2*MonthDur, 2*MonthDur+15*DayDur)
test("1 year", YearDur, YearDur+6*MonthDur)
test("2 years", 2*YearDur, 2*YearDur+6*MonthDur)
}
func TestTimeSincePro(t *testing.T) {
assert.Equal(t, "now", timeSincePro(BaseDate, BaseDate, "en"))
// test that a difference of `diff` yields the expected string
test := func(expected string, diff time.Duration) {
actual := timeSincePro(BaseDate, BaseDate.Add(diff), "en")
assert.Equal(t, expected, actual)
assert.Equal(t, "future", timeSincePro(BaseDate.Add(diff), BaseDate, "en"))
}
test("1 second", time.Second)
test("2 seconds", 2*time.Second)
test("1 minute", time.Minute)
test("1 minute, 1 second", time.Minute+time.Second)
test("1 minute, 59 seconds", time.Minute+59*time.Second)
test("2 minutes", 2*time.Minute)
test("1 hour", time.Hour)
test("1 hour, 1 second", time.Hour+time.Second)
test("1 hour, 59 minutes, 59 seconds", time.Hour+59*time.Minute+59*time.Second)
test("2 hours", 2*time.Hour)
test("1 day", DayDur)
test("1 day, 23 hours, 59 minutes, 59 seconds",
DayDur+23*time.Hour+59*time.Minute+59*time.Second)
test("2 days", 2*DayDur)
test("1 week", WeekDur)
test("2 weeks", 2*WeekDur)
test("1 month", MonthDur)
test("3 months", 3*MonthDur)
test("1 year", YearDur)
test("2 years, 3 months, 1 week, 2 days, 4 hours, 12 minutes, 17 seconds",
2*YearDur+3*MonthDur+WeekDur+2*DayDur+4*time.Hour+
12*time.Minute+17*time.Second)
}
func TestHtmlTimeSince(t *testing.T) {
setting.TimeFormat = time.UnixDate
setting.DefaultUILocation = time.UTC
// test that `diff` yields a result containing `expected`
test := func(expected string, diff time.Duration) {
actual := htmlTimeSince(BaseDate, BaseDate.Add(diff), "en")
assert.Contains(t, actual, `title="Sat Jan 1 00:00:00 UTC 2000"`)
assert.Contains(t, actual, expected)
}
test("1 second", time.Second)
test("3 minutes", 3*time.Minute+5*time.Second)
test("1 day", DayDur+18*time.Hour)
test("1 week", WeekDur+6*DayDur)
test("3 months", 3*MonthDur+3*WeekDur)
test("2 years", 2*YearDur)
test("3 years", 3*YearDur+11*MonthDur+4*WeekDur)
}
func TestComputeTimeDiff(t *testing.T) {
// test that for each offset in offsets,
// computeTimeDiff(base + offset) == (offset, str)
test := func(base int64, str string, offsets ...int64) {
for _, offset := range offsets {
diff, diffStr := computeTimeDiff(base+offset, "en")
assert.Equal(t, offset, diff)
assert.Equal(t, str, diffStr)
}
}
test(0, "now", 0)
test(1, "1 second", 0)
test(2, "2 seconds", 0)
test(Minute, "1 minute", 0, 1, 30, Minute-1)
test(2*Minute, "2 minutes", 0, Minute-1)
test(Hour, "1 hour", 0, 1, Hour-1)
test(5*Hour, "5 hours", 0, Hour-1)
test(Day, "1 day", 0, 1, Day-1)
test(5*Day, "5 days", 0, Day-1)
test(Week, "1 week", 0, 1, Week-1)
test(3*Week, "3 weeks", 0, 4*Day+25000)
test(Month, "1 month", 0, 1, Month-1)
test(10*Month, "10 months", 0, Month-1)
test(Year, "1 year", 0, Year-1)
test(3*Year, "3 years", 0, Year-1)
}
func TestMinutesToFriendly(t *testing.T) {
// test that a number of minutes yields the expected string
test := func(expected string, minutes int) {
actual := MinutesToFriendly(minutes, "en")
assert.Equal(t, expected, actual)
}
test("1 minute", 1)
test("2 minutes", 2)
test("1 hour", 60)
test("1 hour, 1 minute", 61)
test("1 hour, 2 minutes", 62)
test("2 hours", 120)
}

View File

@ -2,7 +2,7 @@
// Use of this source code is governed by a MIT-style // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
package util package timeutil
import ( import (
"time" "time"
@ -35,19 +35,34 @@ func (ts TimeStamp) Year() int {
// AsTime convert timestamp as time.Time in Local locale // AsTime convert timestamp as time.Time in Local locale
func (ts TimeStamp) AsTime() (tm time.Time) { func (ts TimeStamp) AsTime() (tm time.Time) {
tm = time.Unix(int64(ts), 0).In(setting.UILocation) return ts.AsTimeInLocation(setting.DefaultUILocation)
}
// AsTimeInLocation convert timestamp as time.Time in Local locale
func (ts TimeStamp) AsTimeInLocation(loc *time.Location) (tm time.Time) {
tm = time.Unix(int64(ts), 0).In(loc)
return return
} }
// AsTimePtr convert timestamp as *time.Time in Local locale // AsTimePtr convert timestamp as *time.Time in Local locale
func (ts TimeStamp) AsTimePtr() *time.Time { func (ts TimeStamp) AsTimePtr() *time.Time {
tm := time.Unix(int64(ts), 0).In(setting.UILocation) return ts.AsTimePtrInLocation(setting.DefaultUILocation)
}
// AsTimePtrInLocation convert timestamp as *time.Time in customize location
func (ts TimeStamp) AsTimePtrInLocation(loc *time.Location) *time.Time {
tm := time.Unix(int64(ts), 0).In(loc)
return &tm return &tm
} }
// Format formats timestamp as // Format formats timestamp as given format
func (ts TimeStamp) Format(f string) string { func (ts TimeStamp) Format(f string) string {
return ts.AsTime().Format(f) return ts.FormatInLocation(f, setting.DefaultUILocation)
}
// FormatInLocation formats timestamp as given format with spiecific location
func (ts TimeStamp) FormatInLocation(f string, loc *time.Location) string {
return ts.AsTimeInLocation(loc).Format(f)
} }
// FormatLong formats as RFC1123Z // FormatLong formats as RFC1123Z
@ -62,5 +77,5 @@ func (ts TimeStamp) FormatShort() string {
// IsZero is zero time // IsZero is zero time
func (ts TimeStamp) IsZero() bool { func (ts TimeStamp) IsZero() bool {
return ts.AsTime().IsZero() return ts.AsTimeInLocation(time.Local).IsZero()
} }

View File

@ -1959,10 +1959,6 @@ $(document).ready(function () {
// Show exact time // Show exact time
$('.time-since').each(function () { $('.time-since').each(function () {
const time = new Date($(this).attr('title'))
if (!isNaN(time)){
$(this).attr('title', time.toLocaleString())
}
$(this).addClass('poping up').attr('data-content', $(this).attr('title')).attr('data-variation', 'inverted tiny').attr('title', ''); $(this).addClass('poping up').attr('data-content', $(this).attr('title')).attr('data-variation', 'inverted tiny').attr('title', '');
}); });

View File

@ -24,6 +24,7 @@ import (
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/process" "code.gitea.io/gitea/modules/process"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/timeutil"
) )
const ( const (
@ -78,7 +79,7 @@ var sysStatus struct {
} }
func updateSystemStatus() { func updateSystemStatus() {
sysStatus.Uptime = base.TimeSincePro(startTime, "en") sysStatus.Uptime = timeutil.TimeSincePro(startTime, "en")
m := new(runtime.MemStats) m := new(runtime.MemStats)
runtime.ReadMemStats(m) runtime.ReadMemStats(m)

View File

@ -16,6 +16,7 @@ import (
issue_indexer "code.gitea.io/gitea/modules/indexer/issues" issue_indexer "code.gitea.io/gitea/modules/indexer/issues"
"code.gitea.io/gitea/modules/notification" "code.gitea.io/gitea/modules/notification"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/timeutil"
"code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/util"
api "code.gitea.io/gitea/modules/structs" api "code.gitea.io/gitea/modules/structs"
@ -183,9 +184,9 @@ func CreateIssue(ctx *context.APIContext, form api.CreateIssueOption) {
// "201": // "201":
// "$ref": "#/responses/Issue" // "$ref": "#/responses/Issue"
var deadlineUnix util.TimeStamp var deadlineUnix timeutil.TimeStamp
if form.Deadline != nil && ctx.Repo.CanWrite(models.UnitTypeIssues) { if form.Deadline != nil && ctx.Repo.CanWrite(models.UnitTypeIssues) {
deadlineUnix = util.TimeStamp(form.Deadline.Unix()) deadlineUnix = timeutil.TimeStamp(form.Deadline.Unix())
} }
issue := &models.Issue{ issue := &models.Issue{
@ -310,9 +311,9 @@ func EditIssue(ctx *context.APIContext, form api.EditIssueOption) {
} }
// Update the deadline // Update the deadline
var deadlineUnix util.TimeStamp var deadlineUnix timeutil.TimeStamp
if form.Deadline != nil && !form.Deadline.IsZero() && ctx.Repo.CanWrite(models.UnitTypeIssues) { if form.Deadline != nil && !form.Deadline.IsZero() && ctx.Repo.CanWrite(models.UnitTypeIssues) {
deadlineUnix = util.TimeStamp(form.Deadline.Unix()) deadlineUnix = timeutil.TimeStamp(form.Deadline.Unix())
} }
if err := models.UpdateIssueDeadline(issue, deadlineUnix, ctx.User); err != nil { if err := models.UpdateIssueDeadline(issue, deadlineUnix, ctx.User); err != nil {
@ -430,12 +431,12 @@ func UpdateIssueDeadline(ctx *context.APIContext, form api.EditDeadlineOption) {
return return
} }
var deadlineUnix util.TimeStamp var deadlineUnix timeutil.TimeStamp
var deadline time.Time var deadline time.Time
if form.Deadline != nil && !form.Deadline.IsZero() { if form.Deadline != nil && !form.Deadline.IsZero() {
deadline = time.Date(form.Deadline.Year(), form.Deadline.Month(), form.Deadline.Day(), deadline = time.Date(form.Deadline.Year(), form.Deadline.Month(), form.Deadline.Day(),
23, 59, 59, 0, form.Deadline.Location()) 23, 59, 59, 0, form.Deadline.Location())
deadlineUnix = util.TimeStamp(deadline.Unix()) deadlineUnix = timeutil.TimeStamp(deadline.Unix())
} }
if err := models.UpdateIssueDeadline(issue, deadlineUnix, ctx.User); err != nil { if err := models.UpdateIssueDeadline(issue, deadlineUnix, ctx.User); err != nil {

View File

@ -9,9 +9,8 @@ import (
"code.gitea.io/gitea/models" "code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/util"
api "code.gitea.io/gitea/modules/structs" api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/timeutil"
) )
// ListMilestones list milestones for a repository // ListMilestones list milestones for a repository
@ -127,7 +126,7 @@ func CreateMilestone(ctx *context.APIContext, form api.CreateMilestoneOption) {
RepoID: ctx.Repo.Repository.ID, RepoID: ctx.Repo.Repository.ID,
Name: form.Title, Name: form.Title,
Content: form.Description, Content: form.Description,
DeadlineUnix: util.TimeStamp(form.Deadline.Unix()), DeadlineUnix: timeutil.TimeStamp(form.Deadline.Unix()),
} }
if err := models.NewMilestone(milestone); err != nil { if err := models.NewMilestone(milestone); err != nil {
@ -187,7 +186,7 @@ func EditMilestone(ctx *context.APIContext, form api.EditMilestoneOption) {
milestone.Content = *form.Description milestone.Content = *form.Description
} }
if form.Deadline != nil && !form.Deadline.IsZero() { if form.Deadline != nil && !form.Deadline.IsZero() {
milestone.DeadlineUnix = util.TimeStamp(form.Deadline.Unix()) milestone.DeadlineUnix = timeutil.TimeStamp(form.Deadline.Unix())
} }
if err := models.UpdateMilestone(milestone); err != nil { if err := models.UpdateMilestone(milestone); err != nil {

View File

@ -17,7 +17,7 @@ import (
"code.gitea.io/gitea/modules/notification" "code.gitea.io/gitea/modules/notification"
"code.gitea.io/gitea/modules/pull" "code.gitea.io/gitea/modules/pull"
api "code.gitea.io/gitea/modules/structs" api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/timeutil"
) )
// ListPullRequests returns a list of all PRs // ListPullRequests returns a list of all PRs
@ -247,9 +247,9 @@ func CreatePullRequest(ctx *context.APIContext, form api.CreatePullRequestOption
return return
} }
var deadlineUnix util.TimeStamp var deadlineUnix timeutil.TimeStamp
if form.Deadline != nil { if form.Deadline != nil {
deadlineUnix = util.TimeStamp(form.Deadline.Unix()) deadlineUnix = timeutil.TimeStamp(form.Deadline.Unix())
} }
maxIndex, err := models.GetMaxIndexOfIssue(repo.ID) maxIndex, err := models.GetMaxIndexOfIssue(repo.ID)
@ -375,9 +375,9 @@ func EditPullRequest(ctx *context.APIContext, form api.EditPullRequestOption) {
} }
// Update Deadline // Update Deadline
var deadlineUnix util.TimeStamp var deadlineUnix timeutil.TimeStamp
if form.Deadline != nil && !form.Deadline.IsZero() { if form.Deadline != nil && !form.Deadline.IsZero() {
deadlineUnix = util.TimeStamp(form.Deadline.Unix()) deadlineUnix = timeutil.TimeStamp(form.Deadline.Unix())
} }
if err := models.UpdateIssueDeadline(issue, deadlineUnix, ctx.User); err != nil { if err := models.UpdateIssueDeadline(issue, deadlineUnix, ctx.User); err != nil {

View File

@ -9,6 +9,7 @@ import (
"code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/base"
"code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/timeutil"
) )
// TemplatePreview render for previewing the indicated template // TemplatePreview render for previewing the indicated template
@ -18,8 +19,8 @@ func TemplatePreview(ctx *context.Context) {
ctx.Data["AppVer"] = setting.AppVer ctx.Data["AppVer"] = setting.AppVer
ctx.Data["AppUrl"] = setting.AppURL ctx.Data["AppUrl"] = setting.AppURL
ctx.Data["Code"] = "2014031910370000009fff6782aadb2162b4a997acb69d4400888e0b9274657374" ctx.Data["Code"] = "2014031910370000009fff6782aadb2162b4a997acb69d4400888e0b9274657374"
ctx.Data["ActiveCodeLives"] = base.MinutesToFriendly(setting.Service.ActiveCodeLives, ctx.Locale.Language()) ctx.Data["ActiveCodeLives"] = timeutil.MinutesToFriendly(setting.Service.ActiveCodeLives, ctx.Locale.Language())
ctx.Data["ResetPwdCodeLives"] = base.MinutesToFriendly(setting.Service.ResetPwdCodeLives, ctx.Locale.Language()) ctx.Data["ResetPwdCodeLives"] = timeutil.MinutesToFriendly(setting.Service.ResetPwdCodeLives, ctx.Locale.Language())
ctx.Data["CurDbValue"] = "" ctx.Data["CurDbValue"] = ""
ctx.HTML(200, base.TplName(ctx.Params("*"))) ctx.HTML(200, base.TplName(ctx.Params("*")))

View File

@ -7,7 +7,7 @@ package private
import ( import (
"code.gitea.io/gitea/models" "code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/timeutil"
macaron "gopkg.in/macaron.v1" macaron "gopkg.in/macaron.v1"
) )
@ -34,7 +34,7 @@ func UpdatePublicKeyInRepo(ctx *macaron.Context) {
}) })
return return
} }
deployKey.UpdatedUnix = util.TimeStampNow() deployKey.UpdatedUnix = timeutil.TimeStampNow()
if err = models.UpdateDeployKeyCols(deployKey, "updated_unix"); err != nil { if err = models.UpdateDeployKeyCols(deployKey, "updated_unix"); err != nil {
ctx.JSON(500, map[string]interface{}{ ctx.JSON(500, map[string]interface{}{
"err": err.Error(), "err": err.Error(),

View File

@ -14,7 +14,6 @@ import (
"strings" "strings"
"code.gitea.io/gitea/models" "code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/base"
"code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/git"
@ -22,7 +21,7 @@ import (
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/markup" "code.gitea.io/gitea/modules/markup"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/timeutil"
) )
const ( const (
@ -212,7 +211,7 @@ func renderBlame(ctx *context.Context, blameParts []git.BlamePart, commitNames m
if index == 0 { if index == 0 {
// User avatar image // User avatar image
avatar := "" avatar := ""
commitSince := base.TimeSinceUnix(util.TimeStamp(commit.Author.When.Unix()), ctx.Data["Lang"].(string)) commitSince := timeutil.TimeSinceUnix(timeutil.TimeStamp(commit.Author.When.Unix()), ctx.Data["Lang"].(string))
if commit.User != nil { if commit.User != nil {
authorName := commit.Author.Name authorName := commit.Author.Name
if len(commit.User.FullName) > 0 { if len(commit.User.FullName) > 0 {

View File

@ -25,7 +25,7 @@ import (
"code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/timeutil"
) )
// HTTP implmentation git smart HTTP protocol // HTTP implmentation git smart HTTP protocol
@ -203,7 +203,7 @@ func HTTP(ctx *context.Context) {
return return
} }
} }
token.UpdatedUnix = util.TimeStampNow() token.UpdatedUnix = timeutil.TimeStampNow()
if err = models.UpdateAccessToken(token); err != nil { if err = models.UpdateAccessToken(token); err != nil {
ctx.ServerError("UpdateAccessToken", err) ctx.ServerError("UpdateAccessToken", err)
} }

View File

@ -13,6 +13,7 @@ import (
"code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/markup/markdown" "code.gitea.io/gitea/modules/markup/markdown"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/timeutil"
"code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/util"
) )
@ -120,7 +121,7 @@ func NewMilestonePost(ctx *context.Context, form auth.CreateMilestoneForm) {
RepoID: ctx.Repo.Repository.ID, RepoID: ctx.Repo.Repository.ID,
Name: form.Title, Name: form.Title,
Content: form.Content, Content: form.Content,
DeadlineUnix: util.TimeStamp(deadline.Unix()), DeadlineUnix: timeutil.TimeStamp(deadline.Unix()),
}); err != nil { }); err != nil {
ctx.ServerError("NewMilestone", err) ctx.ServerError("NewMilestone", err)
return return
@ -190,7 +191,7 @@ func EditMilestonePost(ctx *context.Context, form auth.CreateMilestoneForm) {
} }
m.Name = form.Title m.Name = form.Title
m.Content = form.Content m.Content = form.Content
m.DeadlineUnix = util.TimeStamp(deadline.Unix()) m.DeadlineUnix = timeutil.TimeStamp(deadline.Unix())
if err = models.UpdateMilestone(m); err != nil { if err = models.UpdateMilestone(m); err != nil {
ctx.ServerError("UpdateMilestone", err) ctx.ServerError("UpdateMilestone", err)
return return
@ -223,7 +224,7 @@ func ChangeMilestonStatus(ctx *context.Context) {
ctx.Redirect(ctx.Repo.RepoLink + "/milestones?state=open") ctx.Redirect(ctx.Repo.RepoLink + "/milestones?state=open")
case "close": case "close":
if !m.IsClosed { if !m.IsClosed {
m.ClosedDateUnix = util.TimeStampNow() m.ClosedDateUnix = timeutil.TimeStampNow()
if err = models.ChangeMilestoneStatus(m, true); err != nil { if err = models.ChangeMilestoneStatus(m, true); err != nil {
ctx.ServerError("ChangeMilestoneStatus", err) ctx.ServerError("ChangeMilestoneStatus", err)
return return

View File

@ -14,9 +14,6 @@ import (
"strings" "strings"
"time" "time"
"github.com/Unknwon/com"
"mvdan.cc/xurls/v2"
"code.gitea.io/gitea/models" "code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/auth" "code.gitea.io/gitea/modules/auth"
"code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/base"
@ -24,9 +21,12 @@ import (
"code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/timeutil"
"code.gitea.io/gitea/modules/validation" "code.gitea.io/gitea/modules/validation"
"code.gitea.io/gitea/routers/utils" "code.gitea.io/gitea/routers/utils"
"github.com/Unknwon/com"
"mvdan.cc/xurls/v2"
) )
const ( const (
@ -144,7 +144,7 @@ func SettingsPost(ctx *context.Context, form auth.RepoSettingForm) {
ctx.Repo.Mirror.EnablePrune = form.EnablePrune ctx.Repo.Mirror.EnablePrune = form.EnablePrune
ctx.Repo.Mirror.Interval = interval ctx.Repo.Mirror.Interval = interval
if interval != 0 { if interval != 0 {
ctx.Repo.Mirror.NextUpdateUnix = util.TimeStampNow().AddDuration(interval) ctx.Repo.Mirror.NextUpdateUnix = timeutil.TimeStampNow().AddDuration(interval)
} else { } else {
ctx.Repo.Mirror.NextUpdateUnix = 0 ctx.Repo.Mirror.NextUpdateUnix = 0
} }

View File

@ -19,6 +19,7 @@ import (
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/markup" "code.gitea.io/gitea/modules/markup"
"code.gitea.io/gitea/modules/markup/markdown" "code.gitea.io/gitea/modules/markup/markdown"
"code.gitea.io/gitea/modules/timeutil"
"code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/util"
) )
@ -58,7 +59,7 @@ func MustEnableWiki(ctx *context.Context) {
type PageMeta struct { type PageMeta struct {
Name string Name string
SubURL string SubURL string
UpdatedUnix util.TimeStamp UpdatedUnix timeutil.TimeStamp
} }
// findEntryForFile finds the tree entry for a target filepath. // findEntryForFile finds the tree entry for a target filepath.
@ -413,7 +414,7 @@ func WikiPages(ctx *context.Context) {
pages = append(pages, PageMeta{ pages = append(pages, PageMeta{
Name: wikiName, Name: wikiName,
SubURL: models.WikiNameToSubURL(wikiName), SubURL: models.WikiNameToSubURL(wikiName),
UpdatedUnix: util.TimeStamp(c.Author.When.Unix()), UpdatedUnix: timeutil.TimeStamp(c.Author.When.Unix()),
}) })
} }
ctx.Data["Pages"] = pages ctx.Data["Pages"] = pages

View File

@ -19,6 +19,7 @@ import (
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/recaptcha" "code.gitea.io/gitea/modules/recaptcha"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/timeutil"
"code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/util"
"github.com/go-macaron/captcha" "github.com/go-macaron/captcha"
@ -950,7 +951,7 @@ func LinkAccountPostRegister(ctx *context.Context, cpt *captcha.Captcha, form au
models.SendActivateAccountMail(ctx.Context, u) models.SendActivateAccountMail(ctx.Context, u)
ctx.Data["IsSendRegisterMail"] = true ctx.Data["IsSendRegisterMail"] = true
ctx.Data["Email"] = u.Email ctx.Data["Email"] = u.Email
ctx.Data["ActiveCodeLives"] = base.MinutesToFriendly(setting.Service.ActiveCodeLives, ctx.Locale.Language()) ctx.Data["ActiveCodeLives"] = timeutil.MinutesToFriendly(setting.Service.ActiveCodeLives, ctx.Locale.Language())
ctx.HTML(200, TplActivate) ctx.HTML(200, TplActivate)
if err := ctx.Cache.Put("MailResendLimit_"+u.LowerName, u.LowerName, 180); err != nil { if err := ctx.Cache.Put("MailResendLimit_"+u.LowerName, u.LowerName, 180); err != nil {
@ -1096,7 +1097,7 @@ func SignUpPost(ctx *context.Context, cpt *captcha.Captcha, form auth.RegisterFo
models.SendActivateAccountMail(ctx.Context, u) models.SendActivateAccountMail(ctx.Context, u)
ctx.Data["IsSendRegisterMail"] = true ctx.Data["IsSendRegisterMail"] = true
ctx.Data["Email"] = u.Email ctx.Data["Email"] = u.Email
ctx.Data["ActiveCodeLives"] = base.MinutesToFriendly(setting.Service.ActiveCodeLives, ctx.Locale.Language()) ctx.Data["ActiveCodeLives"] = timeutil.MinutesToFriendly(setting.Service.ActiveCodeLives, ctx.Locale.Language())
ctx.HTML(200, TplActivate) ctx.HTML(200, TplActivate)
if err := ctx.Cache.Put("MailResendLimit_"+u.LowerName, u.LowerName, 180); err != nil { if err := ctx.Cache.Put("MailResendLimit_"+u.LowerName, u.LowerName, 180); err != nil {
@ -1123,7 +1124,7 @@ func Activate(ctx *context.Context) {
if ctx.Cache.IsExist("MailResendLimit_" + ctx.User.LowerName) { if ctx.Cache.IsExist("MailResendLimit_" + ctx.User.LowerName) {
ctx.Data["ResendLimited"] = true ctx.Data["ResendLimited"] = true
} else { } else {
ctx.Data["ActiveCodeLives"] = base.MinutesToFriendly(setting.Service.ActiveCodeLives, ctx.Locale.Language()) ctx.Data["ActiveCodeLives"] = timeutil.MinutesToFriendly(setting.Service.ActiveCodeLives, ctx.Locale.Language())
models.SendActivateAccountMail(ctx.Context, ctx.User) models.SendActivateAccountMail(ctx.Context, ctx.User)
if err := ctx.Cache.Put("MailResendLimit_"+ctx.User.LowerName, ctx.User.LowerName, 180); err != nil { if err := ctx.Cache.Put("MailResendLimit_"+ctx.User.LowerName, ctx.User.LowerName, 180); err != nil {
@ -1224,7 +1225,7 @@ func ForgotPasswdPost(ctx *context.Context) {
u, err := models.GetUserByEmail(email) u, err := models.GetUserByEmail(email)
if err != nil { if err != nil {
if models.IsErrUserNotExist(err) { if models.IsErrUserNotExist(err) {
ctx.Data["ResetPwdCodeLives"] = base.MinutesToFriendly(setting.Service.ResetPwdCodeLives, ctx.Locale.Language()) ctx.Data["ResetPwdCodeLives"] = timeutil.MinutesToFriendly(setting.Service.ResetPwdCodeLives, ctx.Locale.Language())
ctx.Data["IsResetSent"] = true ctx.Data["IsResetSent"] = true
ctx.HTML(200, tplForgotPassword) ctx.HTML(200, tplForgotPassword)
return return
@ -1251,7 +1252,7 @@ func ForgotPasswdPost(ctx *context.Context) {
log.Error("Set cache(MailResendLimit) fail: %v", err) log.Error("Set cache(MailResendLimit) fail: %v", err)
} }
ctx.Data["ResetPwdCodeLives"] = base.MinutesToFriendly(setting.Service.ResetPwdCodeLives, ctx.Locale.Language()) ctx.Data["ResetPwdCodeLives"] = timeutil.MinutesToFriendly(setting.Service.ResetPwdCodeLives, ctx.Locale.Language())
ctx.Data["IsResetSent"] = true ctx.Data["IsResetSent"] = true
ctx.HTML(200, tplForgotPassword) ctx.HTML(200, tplForgotPassword)
} }

View File

@ -17,6 +17,7 @@ import (
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/recaptcha" "code.gitea.io/gitea/modules/recaptcha"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/timeutil"
"github.com/go-macaron/captcha" "github.com/go-macaron/captcha"
) )
@ -446,7 +447,7 @@ func RegisterOpenIDPost(ctx *context.Context, cpt *captcha.Captcha, form auth.Si
models.SendActivateAccountMail(ctx.Context, u) models.SendActivateAccountMail(ctx.Context, u)
ctx.Data["IsSendRegisterMail"] = true ctx.Data["IsSendRegisterMail"] = true
ctx.Data["Email"] = u.Email ctx.Data["Email"] = u.Email
ctx.Data["ActiveCodeLives"] = base.MinutesToFriendly(setting.Service.ActiveCodeLives, ctx.Locale.Language()) ctx.Data["ActiveCodeLives"] = timeutil.MinutesToFriendly(setting.Service.ActiveCodeLives, ctx.Locale.Language())
ctx.HTML(200, TplActivate) ctx.HTML(200, TplActivate)
if err := ctx.Cache.Put("MailResendLimit_"+u.LowerName, u.LowerName, 180); err != nil { if err := ctx.Cache.Put("MailResendLimit_"+u.LowerName, u.LowerName, 180); err != nil {

View File

@ -7,7 +7,6 @@ package user
import ( import (
"encoding/base64" "encoding/base64"
"fmt" "fmt"
"github.com/go-macaron/binding"
"net/url" "net/url"
"strings" "strings"
@ -17,9 +16,10 @@ import (
"code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/timeutil"
"github.com/dgrijalva/jwt-go" "github.com/dgrijalva/jwt-go"
"github.com/go-macaron/binding"
) )
const ( const (
@ -118,7 +118,7 @@ func newAccessTokenResponse(grant *models.OAuth2Grant) (*AccessTokenResponse, *A
} }
} }
// generate access token to access the API // generate access token to access the API
expirationDate := util.TimeStampNow().Add(setting.OAuth2.AccessTokenExpirationTime) expirationDate := timeutil.TimeStampNow().Add(setting.OAuth2.AccessTokenExpirationTime)
accessToken := &models.OAuth2Token{ accessToken := &models.OAuth2Token{
GrantID: grant.ID, GrantID: grant.ID,
Type: models.TypeAccessToken, Type: models.TypeAccessToken,
@ -135,7 +135,7 @@ func newAccessTokenResponse(grant *models.OAuth2Grant) (*AccessTokenResponse, *A
} }
// generate refresh token to request an access token after it expired later // generate refresh token to request an access token after it expired later
refreshExpirationDate := util.TimeStampNow().Add(setting.OAuth2.RefreshTokenExpirationTime * 60 * 60).AsTime().Unix() refreshExpirationDate := timeutil.TimeStampNow().Add(setting.OAuth2.RefreshTokenExpirationTime * 60 * 60).AsTime().Unix()
refreshToken := &models.OAuth2Token{ refreshToken := &models.OAuth2Token{
GrantID: grant.ID, GrantID: grant.ID,
Counter: grant.Counter, Counter: grant.Counter,

View File

@ -12,6 +12,7 @@ import (
"code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/timeutil"
) )
const ( const (
@ -112,7 +113,7 @@ func EmailPost(ctx *context.Context, form auth.AddEmailForm) {
if err := ctx.Cache.Put("MailResendLimit_"+ctx.User.LowerName, ctx.User.LowerName, 180); err != nil { if err := ctx.Cache.Put("MailResendLimit_"+ctx.User.LowerName, ctx.User.LowerName, 180); err != nil {
log.Error("Set cache(MailResendLimit) fail: %v", err) log.Error("Set cache(MailResendLimit) fail: %v", err)
} }
ctx.Flash.Info(ctx.Tr("settings.add_email_confirmation_sent", email.Email, base.MinutesToFriendly(setting.Service.ActiveCodeLives, ctx.Locale.Language()))) ctx.Flash.Info(ctx.Tr("settings.add_email_confirmation_sent", email.Email, timeutil.MinutesToFriendly(setting.Service.ActiveCodeLives, ctx.Locale.Language())))
} else { } else {
ctx.Flash.Success(ctx.Tr("settings.add_email_success")) ctx.Flash.Success(ctx.Tr("settings.add_email_success"))
} }

View File

@ -9770,7 +9770,7 @@
"description": "TimeStamp defines a timestamp", "description": "TimeStamp defines a timestamp",
"type": "integer", "type": "integer",
"format": "int64", "format": "int64",
"x-go-package": "code.gitea.io/gitea/modules/util" "x-go-package": "code.gitea.io/gitea/modules/timeutil"
}, },
"TrackedTime": { "TrackedTime": {
"description": "TrackedTime worked time for an issue / pr", "description": "TrackedTime worked time for an issue / pr",