Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions datetime.go
Original file line number Diff line number Diff line change
Expand Up @@ -617,6 +617,7 @@ type DateTimer interface {
Century(v reflect.Value) (interface{}, error)
TimeZone(v reflect.Value) (interface{}, error)
TimePeriod(v reflect.Value) (interface{}, error)
UTCTimestampValue(v reflect.Value) (interface{}, error)
}

// GetDateTimer returns a new DateTimer interface of DateTime
Expand Down Expand Up @@ -828,3 +829,24 @@ func Timeperiod(opts ...options.OptionFunc) string {
func RandomUnixTime() int64 {
return rand.Int63n(time.Now().Unix())
}

// UTCTimestamp generates a random time.Time in UTC
func (d DateTime) UTCTimestamp() time.Time {
return time.Unix(RandomUnixTime(), 0).UTC()
}

// UTCTimestamp handles time.Time fields for utc_timestamp tag
func (d DateTime) UTCTimestampValue(v reflect.Value) (interface{}, error) {
if v.Type() != reflect.TypeOf(time.Time{}) {
return nil, fmt.Errorf("UTCTimestamp only supports time.Time, got %v", v.Type())
}
return d.UTCTimestamp(), nil
}

// UTCTimestamp generates a random UTC timestamp for a struct field
func UTCTimestamp(opts ...options.OptionFunc) time.Time {
return singleFakeData(UTCTimestampTag, func() interface{} {
datetime := DateTime{}
return datetime.UTCTimestamp()
}, opts...).(time.Time)
}
24 changes: 24 additions & 0 deletions datetime_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -254,3 +254,27 @@ func TestFakeTimePeriod(t *testing.T) {
t.Error("function TimePeriod need return valid period")
}
}

func TestUTCTimestampValueValid(t *testing.T) {
d := GetDateTimer()
var ref = struct {
some time.Time
}{
some: time.Time{},
}
val, err := d.UTCTimestampValue(reflect.ValueOf(&ref.some).Elem())
if err != nil {
t.Error("function UTCTimestampValue need return valid value")
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
t.Error("function UTCTimestampValue need return valid value")
t.Error("function UTCTimestampValue needs to return a valid value")

}

result, ok := val.(time.Time)
if !ok {
t.Error("UTCTimestampValue should return time.Time")
}
if result.Location() != time.UTC {
t.Error("UTCTimestampValue should return time in UTC")
}
if time.Now().Unix() <= result.Unix() {
t.Error("UTCTimestamp should return time <= now")
Comment on lines +277 to +278
Copy link
Member

Choose a reason for hiding this comment

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

Let's make this condition easier to understand and consistent with the error message.

Suggested change
if time.Now().Unix() <= result.Unix() {
t.Error("UTCTimestamp should return time <= now")
if result.Unix() > time.Now().Unix() {
t.Error("UTCTimestamp should return time <= now")

We should use > instead of >= because if result == now, the current logic would still trigger an error, even though it satisfies the expectation (result <= now).

}
}
23 changes: 12 additions & 11 deletions example_single_fake_data_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,18 @@ func Example_singleFakeData() {
fmt.Println(faker.GetRealAddress()) // => {2755 Country Drive Fremont CA 94536 {37.557882 -121.986823}}

// Datetime
fmt.Println(faker.UnixTime()) // => 1197930901
fmt.Println(faker.Date()) // => 1982-02-27
fmt.Println(faker.TimeString()) // => 03:10:25
fmt.Println(faker.MonthName()) // => February
fmt.Println(faker.YearString()) // => 1994
fmt.Println(faker.DayOfWeek()) // => Sunday
fmt.Println(faker.DayOfMonth()) // => 20
fmt.Println(faker.Timestamp()) // => 1973-06-21 14:50:46
fmt.Println(faker.Century()) // => IV
fmt.Println(faker.Timezone()) // => Asia/Jakarta
fmt.Println(faker.Timeperiod()) // => PM
fmt.Println(faker.UnixTime()) // => 1197930901
fmt.Println(faker.Date()) // => 1982-02-27
fmt.Println(faker.TimeString()) // => 03:10:25
fmt.Println(faker.MonthName()) // => February
fmt.Println(faker.YearString()) // => 1994
fmt.Println(faker.DayOfWeek()) // => Sunday
fmt.Println(faker.DayOfMonth()) // => 20
fmt.Println(faker.Timestamp()) // => 1973-06-21 14:50:46
fmt.Println(faker.Century()) // => IV
fmt.Println(faker.Timezone()) // => Asia/Jakarta
fmt.Println(faker.Timeperiod()) // => PM
fmt.Println(faker.UTCTimestamp()) // => 2025-04-15 12:34:56 +0000 UTC.

// Internet
fmt.Println(faker.Email()) // => [email protected]
Expand Down
2 changes: 2 additions & 0 deletions example_with_tags_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package faker_test

import (
"fmt"
"time"

"github.com/go-faker/faker/v4"
)
Expand Down Expand Up @@ -66,6 +67,7 @@ type SomeStructWithTags struct {
NumU8 uint8 `faker:"oneof: 15, 16"`
NumU uint `faker:"oneof: 17, 18"`
PtrNumU *uint `faker:"oneof: 19, 20"`
UTCTime time.Time `faker:"utc_timestamp"`
}

func Example_withTags() {
Expand Down
5 changes: 4 additions & 1 deletion faker.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ const (
CENTURY = "century"
TIMEZONE = "timezone"
TimePeriodTag = "time_period"
UTCTimestampTag = "utc_timestamp"
WORD = "word"
SENTENCE = "sentence"
PARAGRAPH = "paragraph"
Expand Down Expand Up @@ -104,7 +105,7 @@ var PriorityTags = []string{ID, HyphenatedID, EmailTag, MacAddressTag, DomainNam
IPV6Tag, PASSWORD, JWT, CountryInfoTag, LATITUDE, LONGITUDE, CreditCardNumber, CreditCardType, PhoneNumber, TollFreeNumber,
E164PhoneNumberTag, TitleMaleTag, TitleFemaleTag, FirstNameTag, FirstNameMaleTag, FirstNameFemaleTag, LastNameTag,
NAME, ChineseFirstNameTag, ChineseLastNameTag, ChineseNameTag, GENDER, UnixTimeTag, DATE, TIME, MonthNameTag,
YEAR, DayOfWeekTag, DayOfMonthTag, TIMESTAMP, CENTURY, TIMEZONE, TimePeriodTag, WORD, SENTENCE, PARAGRAPH,
YEAR, DayOfWeekTag, DayOfMonthTag, TIMESTAMP, CENTURY, TIMEZONE, TimePeriodTag, UTCTimestampTag, WORD, SENTENCE, PARAGRAPH,
CurrencyTag, AmountTag, AmountWithCurrencyTag, SKIP, Length, SliceLength, Language, BoundaryStart, BoundaryEnd, ONEOF, BloodTypeTag,
UserAgentTag,
}
Expand Down Expand Up @@ -177,6 +178,7 @@ func initDefaultTag() {
defaultTag.Store(CENTURY, CENTURY)
defaultTag.Store(TIMEZONE, TIMEZONE)
defaultTag.Store(TimePeriodTag, TimePeriodFormat)
defaultTag.Store(UTCTimestampTag, UTCTimestampTag)
defaultTag.Store(WORD, WORD)
defaultTag.Store(SENTENCE, SENTENCE)
defaultTag.Store(PARAGRAPH, PARAGRAPH)
Expand Down Expand Up @@ -226,6 +228,7 @@ func initMapperTagDefault() {
mapperTag.Store(CENTURY, GetDateTimer().Century)
mapperTag.Store(TIMEZONE, GetDateTimer().TimeZone)
mapperTag.Store(TimePeriodTag, GetDateTimer().TimePeriod)
mapperTag.Store(UTCTimestampTag, GetDateTimer().UTCTimestampValue)
mapperTag.Store(WORD, GetLorem().Word)
mapperTag.Store(SENTENCE, GetLorem().Sentence)
mapperTag.Store(PARAGRAPH, GetLorem().Paragraph)
Expand Down
94 changes: 48 additions & 46 deletions faker_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -255,51 +255,52 @@ type CStruct struct {
}

type TaggedStruct struct {
Latitude float32 `faker:"lat" custom_tag_name:"lat" `
Longitude float32 `faker:"long" custom_tag_name:"long"`
CreditCardNumber string `faker:"cc_number" custom_tag_name:"cc_number"`
CreditCardType string `faker:"cc_type" custom_tag_name:"cc_type"`
Email string `faker:"email" custom_tag_name:"email"`
DomainName string `faker:"domain_name" custom_tag_name:"domain_name"`
IPV4 string `faker:"ipv4" custom_tag_name:"ipv4"`
IPV6 string `faker:"ipv6" custom_tag_name:"ipv6"`
Password string `faker:"password" custom_tag_name:"password"`
Jwt string `faker:"jwt" custom_tag_name:"jwt"`
PhoneNumber string `faker:"phone_number" custom_tag_name:"phone_number"`
MacAddress string `faker:"mac_address" custom_tag_name:"mac_address"`
URL string `faker:"url" custom_tag_name:"url"`
UserName string `faker:"username" custom_tag_name:"username"`
TollFreeNumber string `faker:"toll_free_number" custom_tag_name:"toll_free_number"`
E164PhoneNumber string `faker:"e_164_phone_number" custom_tag_name:"e_164_phone_number"`
TitleMale string `faker:"title_male" custom_tag_name:"title_male"`
TitleFemale string `faker:"title_female" custom_tag_name:"title_female"`
FirstName string `faker:"first_name" custom_tag_name:"first_name"`
FirstNameMale string `faker:"first_name_male" custom_tag_name:"first_name_male"`
FirstNameFemale string `faker:"first_name_female" custom_tag_name:"first_name_female"`
LastName string `faker:"last_name" custom_tag_name:"last_name"`
Name string `faker:"name" custom_tag_name:"name"`
ChineseFirstName string `faker:"chinese_first_name" custom_tag_name:"chinese_first_name"`
ChineseLastName string `faker:"chinese_last_name" custom_tag_name:"chinese_last_name"`
ChineseName string `faker:"chinese_name" custom_tag_name:"chinese_name"`
UnixTime int64 `faker:"unix_time" custom_tag_name:"unix_time"`
Date string `faker:"date" custom_tag_name:"date"`
Time string `faker:"time" custom_tag_name:"time"`
MonthName string `faker:"month_name" custom_tag_name:"month_name"`
Year string `faker:"year" custom_tag_name:"year"`
DayOfWeek string `faker:"day_of_week" custom_tag_name:"day_of_week"`
DayOfMonth string `faker:"day_of_month" custom_tag_name:"day_of_month"`
Timestamp string `faker:"timestamp" custom_tag_name:"timestamp"`
Century string `faker:"century" custom_tag_name:"century"`
TimeZone string `faker:"timezone" custom_tag_name:"timezone"`
TimePeriod string `faker:"time_period" custom_tag_name:"time_period"`
Word string `faker:"word" custom_tag_name:"word"`
Sentence string `faker:"sentence" custom_tag_name:"sentence"`
Paragraph string `faker:"paragraph" custom_tag_name:"paragraph"`
Currency string `faker:"currency" custom_tag_name:"currency"`
Amount float32 `faker:"amount" custom_tag_name:"amount"`
AmountWithCurrency string `faker:"amount_with_currency" custom_tag_name:"amount_with_currency"`
ID string `faker:"uuid_digit" custom_tag_name:"uuid_digit"`
HyphenatedID string `faker:"uuid_hyphenated" custom_tag_name:"uuid_hyphenated"`
Latitude float32 `faker:"lat" custom_tag_name:"lat" `
Longitude float32 `faker:"long" custom_tag_name:"long"`
CreditCardNumber string `faker:"cc_number" custom_tag_name:"cc_number"`
CreditCardType string `faker:"cc_type" custom_tag_name:"cc_type"`
Email string `faker:"email" custom_tag_name:"email"`
DomainName string `faker:"domain_name" custom_tag_name:"domain_name"`
IPV4 string `faker:"ipv4" custom_tag_name:"ipv4"`
IPV6 string `faker:"ipv6" custom_tag_name:"ipv6"`
Password string `faker:"password" custom_tag_name:"password"`
Jwt string `faker:"jwt" custom_tag_name:"jwt"`
PhoneNumber string `faker:"phone_number" custom_tag_name:"phone_number"`
MacAddress string `faker:"mac_address" custom_tag_name:"mac_address"`
URL string `faker:"url" custom_tag_name:"url"`
UserName string `faker:"username" custom_tag_name:"username"`
TollFreeNumber string `faker:"toll_free_number" custom_tag_name:"toll_free_number"`
E164PhoneNumber string `faker:"e_164_phone_number" custom_tag_name:"e_164_phone_number"`
TitleMale string `faker:"title_male" custom_tag_name:"title_male"`
TitleFemale string `faker:"title_female" custom_tag_name:"title_female"`
FirstName string `faker:"first_name" custom_tag_name:"first_name"`
FirstNameMale string `faker:"first_name_male" custom_tag_name:"first_name_male"`
FirstNameFemale string `faker:"first_name_female" custom_tag_name:"first_name_female"`
LastName string `faker:"last_name" custom_tag_name:"last_name"`
Name string `faker:"name" custom_tag_name:"name"`
ChineseFirstName string `faker:"chinese_first_name" custom_tag_name:"chinese_first_name"`
ChineseLastName string `faker:"chinese_last_name" custom_tag_name:"chinese_last_name"`
ChineseName string `faker:"chinese_name" custom_tag_name:"chinese_name"`
UnixTime int64 `faker:"unix_time" custom_tag_name:"unix_time"`
Date string `faker:"date" custom_tag_name:"date"`
Time string `faker:"time" custom_tag_name:"time"`
MonthName string `faker:"month_name" custom_tag_name:"month_name"`
Year string `faker:"year" custom_tag_name:"year"`
DayOfWeek string `faker:"day_of_week" custom_tag_name:"day_of_week"`
DayOfMonth string `faker:"day_of_month" custom_tag_name:"day_of_month"`
Timestamp string `faker:"timestamp" custom_tag_name:"timestamp"`
Century string `faker:"century" custom_tag_name:"century"`
TimeZone string `faker:"timezone" custom_tag_name:"timezone"`
TimePeriod string `faker:"time_period" custom_tag_name:"time_period"`
Word string `faker:"word" custom_tag_name:"word"`
Sentence string `faker:"sentence" custom_tag_name:"sentence"`
Paragraph string `faker:"paragraph" custom_tag_name:"paragraph"`
Currency string `faker:"currency" custom_tag_name:"currency"`
Amount float32 `faker:"amount" custom_tag_name:"amount"`
AmountWithCurrency string `faker:"amount_with_currency" custom_tag_name:"amount_with_currency"`
ID string `faker:"uuid_digit" custom_tag_name:"uuid_digit"`
HyphenatedID string `faker:"uuid_hyphenated" custom_tag_name:"uuid_hyphenated"`
UTCTimestamp time.Time `faker:"utc_timestamp" custom_tag_name:"utc_timestamp"`
}

func (t TaggedStruct) String() string {
Expand Down Expand Up @@ -346,6 +347,7 @@ func (t TaggedStruct) String() string {
AmountWithCurrency: %s,
HyphenatedID: %s,
ID: %s,
UTCTimestamp: %v,
}`, t.Latitude, t.Longitude, t.CreditCardNumber,
t.CreditCardType, t.Email, t.DomainName, t.IPV4,
t.IPV6, t.Password, t.Jwt, t.PhoneNumber, t.MacAddress,
Expand All @@ -357,7 +359,7 @@ func (t TaggedStruct) String() string {
t.DayOfMonth, t.Timestamp, t.Century, t.TimeZone,
t.TimePeriod, t.Word, t.Sentence, t.Paragraph,
t.Currency, t.Amount, t.AmountWithCurrency,
t.HyphenatedID, t.ID,
t.HyphenatedID, t.ID, t.UTCTimestamp,
)
}

Expand Down
4 changes: 3 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
module github.com/go-faker/faker/v4

go 1.18
go 1.23.0

toolchain go1.23.5

require golang.org/x/text v0.24.0
Loading