[インデックス 1556] ファイルの概要
このコミットは、Go言語の標準ライブラリであるtime
パッケージ内のTime
構造体のフィールドの可視性を変更するものです。具体的には、Time
構造体の内部フィールドが非公開(unexported)から公開(exported)に変更されています。これに伴い、time
パッケージの内部実装およびテストコードも、新しい公開フィールド名に合わせて修正されています。
変更されたファイルは以下の通りです。
src/lib/Makefile
:time
パッケージのビルド設定に関連する変更。io.dirinstall
への依存が追加されています。src/lib/time/time.go
:Time
構造体のフィールド名が小文字から大文字に修正され、それに伴う内部ロジックのフィールド参照も更新されています。src/lib/time/time_test.go
:Time
構造体のフィールドを参照するテストコードが、新しい公開フィールド名に合わせて修正されています。
コミット
このコミットは、time
パッケージのTime
構造体のフィールドを公開(public)にするための変更です。これにより、Time
オブジェクトの各時間要素(年、月、日、時、分、秒など)に外部から直接アクセスできるようになります。
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/65ad3ce1795c3c1e1a65d7eecbc9f00451068fc8
元コミット内容
make time fields public
R=r
DELTA=49 (0 added, 0 deleted, 49 changed)
OCL=23480
CL=23487
変更の背景
Go言語では、パッケージ内の識別子(変数、関数、型、構造体のフィールドなど)の可視性は、その名前の先頭文字が大文字か小文字かによって決定されます。
- 大文字で始まる識別子: パッケージ外からアクセス可能(exported、公開)
- 小文字で始まる識別子: パッケージ内からのみアクセス可能(unexported、非公開)
このコミットが行われた2009年1月時点のGo言語はまだ開発初期段階であり、API設計の試行錯誤が行われていました。time
パッケージのTime
構造体の各フィールド(year
, month
, day
, hour
, minute
, second
, weekday
, zoneoffset
, zone
)は、元々小文字で始まっており、パッケージ外からは直接アクセスできない非公開の状態でした。
しかし、時間情報を扱うTime
構造体において、その内部要素(年、月、日など)に直接アクセスできることは、ユーザーが柔軟に時間データを操作したり、表示形式をカスタマイズしたりする上で非常に重要です。非公開のままでは、これらの情報にアクセスするためには、別途ゲッターメソッド(例: t.GetYear()
, t.GetMonth()
)を提供する必要があり、APIが冗長になる可能性があります。
この変更の背景には、Time
構造体の各要素をGo言語の慣習に則って直接アクセス可能にすることで、APIの使いやすさと直感性を向上させるという設計判断があったと考えられます。これにより、ユーザーはt.Year
、t.Month
のように直接フィールドにアクセスできるようになり、コードの記述が簡潔になります。
前提知識の解説
Go言語の可視性(Visibility)ルール
Go言語の可視性ルールは非常にシンプルで、識別子の最初の文字が大文字か小文字かによって決まります。
- Exported (公開): 識別子の最初の文字が大文字の場合、その識別子はパッケージ外からアクセス可能です。これは、他のプログラミング言語における
public
に相当します。例えば、fmt.Println
のPrintln
は公開されているため、fmt
パッケージをインポートすればどこからでも呼び出せます。構造体のフィールドが公開されている場合、myStruct.MyField
のように直接アクセスできます。 - Unexported (非公開): 識別子の最初の文字が小文字の場合、その識別子は定義されたパッケージ内からのみアクセス可能です。これは、他のプログラミング言語における
private
やinternal
に相当します。パッケージ外からは直接アクセスできません。
このルールは、API設計において非常に重要です。公開された識別子は、そのパッケージの外部インターフェースとなり、互換性を維持する責任が生じます。非公開の識別子は、パッケージの内部実装の詳細であり、外部からは見えないため、パッケージ開発者は自由に内部を変更できます。
Go言語のtime
パッケージ
Go言語の標準ライブラリには、日付と時刻を扱うためのtime
パッケージが用意されています。このパッケージは、時間の測定、表示、フォーマット、解析、および時間帯の処理など、幅広い機能を提供します。
time.Time
構造体:time
パッケージの中心となる型で、特定の時点(インスタント)を表します。この構造体は、年、月、日、時、分、秒、ナノ秒、タイムゾーン情報などを内部に保持しています。- 時間の表現:
time.Time
は、通常、協定世界時(UTC)または特定のロケーション(タイムゾーン)における時刻を表します。 - 時間の操作:
time.Time
オブジェクトは、加算(Add
)、減算(Sub
)、比較(Before
,After
,Equal
)などのメソッドを提供し、時間の計算や比較を容易にします。 - フォーマットと解析:
Format
メソッドとParse
関数を使用して、時刻を文字列に変換したり、文字列から時刻を解析したりできます。
このコミットは、time.Time
構造体の内部フィールドを公開することで、ユーザーがより直接的に時間要素にアクセスできるようにし、time
パッケージの利便性を高めることを目的としています。
技術的詳細
このコミットの技術的な核心は、Go言語の可視性ルールをtime.Time
構造体のフィールドに適用した点にあります。
-
フィールド名の変更:
year
->Year
month
->Month
day
->Day
hour
->Hour
minute
->Minute
second
->Second
weekday
->Weekday
zoneoffset
->ZoneOffset
zone
->Zone
これらの変更により、
Time
構造体のインスタンスt
がある場合、以前はt.year
のようにアクセスしようとするとコンパイルエラーになっていましたが、変更後はt.Year
のように直接アクセスできるようになります。 -
内部実装の更新:
src/lib/time/time.go
内のSecondsToUTC
,SecondsToLocalTime
,Seconds
,_Format
などの関数やメソッドは、Time
構造体のフィールドにアクセスする際に、新しい公開フィールド名を使用するように修正されています。例えば、t.hour
はt.Hour
に、t.weekday
はt.Weekday
に変更されています。これは、フィールド名が変更されたため、そのフィールドを参照するすべての箇所を更新する必要があるためです。 -
テストコードの更新:
src/lib/time/time_test.go
内の_Same
関数は、2つのTime
オブジェクトが同じであるかを比較する際に、各フィールドを比較しています。この比較も、新しい公開フィールド名に合わせてt.year == u.year
からt.Year == u.Year
のように修正されています。これにより、テストが引き続き正しく機能することが保証されます。 -
Makefileの変更:
src/lib/Makefile
において、time.dirinstall
の依存関係にio.dirinstall
が追加されています。これは、time
パッケージがio
パッケージの機能に依存するようになったことを示唆しています。具体的な依存関係の詳細は、このコミットの差分からは直接読み取れませんが、Go言語の標準ライブラリは相互に依存し合っているため、このような依存関係の追加は一般的なことです。
この変更は、time
パッケージのAPI設計における重要なマイルストーンであり、Go言語の可視性ルールがどのように実際のライブラリ設計に適用されるかを示す良い例です。これにより、time.Time
オブジェクトの各要素へのアクセスがより直接的になり、Go言語の慣習に沿った自然なコード記述が可能になりました。
コアとなるコードの変更箇所
src/lib/time/time.go
Time
構造体の定義部分:
--- a/src/lib/time/time.go
+++ b/src/lib/time/time.go
@@ -38,12 +38,12 @@ const (
)
type Time struct {
- year int64; // 2008 is 2008
- month, day int; // Sep-17 is 9, 17
- hour, minute, second int; // 10:43:12 is 10, 43, 12
- weekday int; // Sunday = 0, Monday = 1, ...
- zoneoffset int; // seconds west of UTC
- zone string;
+ Year int64; // 2008 is 2008
+ Month, Day int; // Sep-17 is 9, 17
+ Hour, Minute, Second int; // 10:43:12 is 10, 43, 12
+ Weekday int; // Sunday = 0, Monday = 1, ...
+ ZoneOffset int; // seconds west of UTC
+ Zone string;
}
SecondsToUTC
関数内のフィールド参照:
--- a/src/lib/time/time.go
+++ b/src/lib/time/time.go
@@ -82,14 +82,14 @@ func SecondsToUTC(sec int64) *Time {
}
// Time
- t.hour = int(sec/3600);
- t.minute = int((sec/60)%60);
- t.second = int(sec%60);
+ t.Hour = int(sec/3600);
+ t.Minute = int((sec/60)%60);
+ t.Second = int(sec%60);
// Day 0 = January 1, 1970 was a Thursday
- t.weekday = int((day + Thursday) % 7);
- if t.weekday < 0 {
- t.weekday += 7
+ t.Weekday = int((day + Thursday) % 7);
+ if t.Weekday < 0 {
+ t.Weekday += 7
}
// Change day from 0 = 1970 to 0 = 2001,
@@ -125,9 +125,9 @@ func SecondsToUTC(sec int64) *Time {
for m = 0; m < 12 && yday >= months[m]; m++ {
yday -= months[m]
}
- t.month = m+1;
- t.day = yday+1;
- t.zone = "GMT";
+ t.Month = m+1;
+ t.Day = yday+1;
+ t.Zone = "GMT";
SecondsToLocalTime
関数内のフィールド参照:
--- a/src/lib/time/time.go
+++ b/src/lib/time/time.go
@@ -154,8 +154,8 @@ func SecondsToLocalTime(sec int64) *Time {
return SecondsToUTC(sec)
}
t := SecondsToUTC(sec+int64(offset));
- t.zone = zone;
- t.zoneoffset = offset;
+ t.Zone = zone;
+ t.ZoneOffset = offset;
return t
}
Seconds
メソッド内のフィールド参照:
--- a/src/lib/time/time.go
+++ b/src/lib/time/time.go
@@ -172,7 +172,7 @@ func (t *Time) Seconds() int64 {
day := int64(0);
// Rewrite year to be >= 2001.
- year := t.year;
+ year := t.Year;
if year < 2001 {
n := (2001 - year)/400 + 1;
year += 400*n;
@@ -199,25 +199,25 @@ func (t *Time) Seconds() int64 {
day += 365*n;
// Add in days this year.
- months := months(t.year);
- for m := 0; m < t.month-1; m++ {
+ months := months(t.Year);
+ for m := 0; m < t.Month-1; m++ {
day += int64(months[m])
}
- day += int64(t.day - 1);
+ day += int64(t.Day - 1);
// Convert days to seconds since January 1, 2001.
sec := day * _SecondsPerDay;
// Add in time elapsed today.
- sec += int64(t.hour) * 3600;
- sec += int64(t.minute) * 60;
- sec += int64(t.second);
+ sec += int64(t.Hour) * 3600;
+ sec += int64(t.Minute) * 60;
+ sec += int64(t.Second);
// Convert from seconds since 2001 to seconds since 1970.
sec += _Days1970To2001 * _SecondsPerDay;
// Account for local time zone.
- sec -= int64(t.zoneoffset);
+ sec -= int64(t.ZoneOffset);
return sec
}
_Format
関数内のフィールド参照:
--- a/src/lib/time/time.go
+++ b/src/lib/time/time.go
@@ -289,39 +289,39 @@ func _Format(t *Time, fmt string) string {
i++;
switch fmt[i] {
case 'A': // %A full weekday name
- bp = _AddString(buf, bp, _LongDayNames[t.weekday]);
+ bp = _AddString(buf, bp, _LongDayNames[t.Weekday]);
case 'a': // %a abbreviated weekday name
- bp = _AddString(buf, bp, _ShortDayNames[t.weekday]);
+ bp = _AddString(buf, bp, _ShortDayNames[t.Weekday]);
case 'b': // %b abbreviated month name
- bp = _AddString(buf, bp, _ShortMonthNames[t.month-1]);
+ bp = _AddString(buf, bp, _ShortMonthNames[t.Month-1]);
case 'd': // %d day of month (01-31)
- _Decimal(buf[bp:bp+2], t.day);
+ _Decimal(buf[bp:bp+2], t.Day);
bp += 2;
case 'e': // %e day of month ( 1-31)
- if t.day >= 10 {
- _Decimal(buf[bp:bp+2], t.day)
+ if t.Day >= 10 {
+ _Decimal(buf[bp:bp+2], t.Day)
} else {
buf[bp] = ' ';
- buf[bp+1] = byte(t.day + '0')
+ buf[bp+1] = byte(t.Day + '0')
}
bp += 2;
case 'H': // %H hour 00-23
- _Decimal(buf[bp:bp+2], t.hour);
+ _Decimal(buf[bp:bp+2], t.Hour);
bp += 2;
case 'M': // %M minute 00-59
- _Decimal(buf[bp:bp+2], t.minute);
+ _Decimal(buf[bp:bp+2], t.Minute);
bp += 2;
case 'S': // %S second 00-59
- _Decimal(buf[bp:bp+2], t.second);
+ _Decimal(buf[bp:bp+2], t.Second);
bp += 2;
case 'Y': // %Y year 2008
- _Decimal(buf[bp:bp+4], int(t.year));
+ _Decimal(buf[bp:bp+4], int(t.Year));
bp += 4;
case 'y': // %y year 08
- _Decimal(buf[bp:bp+2], int(t.year%100));
+ _Decimal(buf[bp:bp+2], int(t.Year%100));
bp += 2;
case 'Z':
- bp = _AddString(buf, bp, t.zone);
+ bp = _AddString(buf, bp, t.Zone);
default:
buf[bp] = '%';
buf[bp+1] = fmt[i];
src/lib/time/time_test.go
_Same
関数内のフィールド比較:
--- a/src/lib/time/time_test.go
+++ b/src/lib/time/time_test.go
@@ -30,15 +30,15 @@ var localtests = []_TimeTest {
}
func _Same(t, u *Time) bool {
- return t.year == u.year
- && t.month == u.month
- && t.day == u.day
- && t.hour == u.hour
- && t.minute == u.minute
- && t.second == u.second
- && t.weekday == u.weekday
- && t.zoneoffset == u.zoneoffset
- && t.zone == u.zone
+ return t.Year == u.Year
+ && t.Month == u.Month
+ && t.Day == u.Day
+ && t.Hour == u.Hour
+ && t.Minute == u.Minute
+ && t.Second == u.Second
+ && t.Weekday == u.Weekday
+ && t.ZoneOffset == u.ZoneOffset
+ && t.Zone == u.Zone
}
コアとなるコードの解説
このコミットの主要な変更は、src/lib/time/time.go
ファイル内のTime
構造体の定義と、その構造体のフィールドを参照するすべてのコード箇所にあります。
-
Time
構造体のフィールド名の変更: 最も重要な変更は、Time
構造体の各フィールド名が小文字から大文字に変更されたことです。 例:year
->Year
,month
->Month
,hour
->Hour
など。 Go言語の可視性ルールにより、これによりこれらのフィールドはパッケージ外から直接アクセス可能な「公開(exported)」フィールドとなりました。これは、time.Time
オブジェクトの各時間要素(年、月、日など)に、myTime.Year
やmyTime.Month
のように直接アクセスできるようになったことを意味します。以前は、これらのフィールドは非公開であったため、パッケージ外からアクセスするには、別途ゲッターメソッド(例:myTime.GetYear()
)が必要でした。この変更により、APIの使いやすさと簡潔性が向上しました。 -
内部ロジックのフィールド参照の更新:
SecondsToUTC
,SecondsToLocalTime
,Seconds
,_Format
といったtime
パッケージ内の関数やメソッドは、Time
構造体のフィールドを操作しています。フィールド名が変更されたため、これらの関数やメソッド内のすべてのフィールド参照も、新しい大文字で始まる名前に更新されています。例えば、t.hour = int(sec/3600)
はt.Hour = int(sec/3600)
に変更されています。これは、コンパイルエラーを避けるために必須の変更です。 -
テストコードの更新:
src/lib/time/time_test.go
内の_Same
関数は、2つのTime
構造体が等しいかどうかを比較するために、そのすべてのフィールドを比較しています。この関数内のフィールド参照も、新しい公開フィールド名に合わせて更新されています。これにより、Time
構造体のフィールドが公開された後も、既存のテストが正しく機能し、変更が意図した通りであることを保証します。
これらの変更は、Go言語のAPI設計における重要な原則、すなわち「外部に公開するものは大文字で始める」という慣習に沿ったものです。これにより、time.Time
構造体はよりGo言語らしい、直感的で使いやすいAPIを提供できるようになりました。
関連リンク
参考にした情報源リンク
- Go言語の可視性ルール (Effective Go - Names)
- Go言語 time パッケージ公式ドキュメント
- Go言語の構造体とフィールドの可視性について (一般的なGo言語の可視性に関する情報源として参照)
- Go言語のtimeパッケージの使い方 (一般的なtimeパッケージの使い方に関する情報源として参照)
- Go言語の歴史と進化 (Go言語の初期開発に関する一般的な背景情報として参照)
- Go言語のコミット履歴 (Go言語のコミット履歴を辿る際の一般的な情報源として参照)```markdown
[インデックス 1556] ファイルの概要
このコミットは、Go言語の標準ライブラリであるtime
パッケージ内のTime
構造体のフィールドの可視性を変更するものです。具体的には、Time
構造体の内部フィールドが非公開(unexported)から公開(exported)に変更されています。これに伴い、time
パッケージの内部実装およびテストコードも、新しい公開フィールド名に合わせて修正されています。
変更されたファイルは以下の通りです。
src/lib/Makefile
:time
パッケージのビルド設定に関連する変更。io.dirinstall
への依存が追加されています。src/lib/time/time.go
:Time
構造体のフィールド名が小文字から大文字に修正され、それに伴う内部ロジックのフィールド参照も更新されています。src/lib/time/time_test.go
:Time
構造体のフィールドを参照するテストコードが、新しい公開フィールド名に合わせて修正されています。
コミット
このコミットは、time
パッケージのTime
構造体のフィールドを公開(public)にするための変更です。これにより、Time
オブジェクトの各時間要素(年、月、日、時、分、秒など)に外部から直接アクセスできるようになります。
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/65ad3ce1795c3c1e1a65d7eecbc9f00451068fc8
元コミット内容
make time fields public
R=r
DELTA=49 (0 added, 0 deleted, 49 changed)
OCL=23480
CL=23487
変更の背景
Go言語では、パッケージ内の識別子(変数、関数、型、構造体のフィールドなど)の可視性は、その名前の先頭文字が大文字か小文字かによって決定されます。
- 大文字で始まる識別子: パッケージ外からアクセス可能(exported、公開)
- 小文字で始まる識別子: パッケージ内からのみアクセス可能(unexported、非公開)
このコミットが行われた2009年1月時点のGo言語はまだ開発初期段階であり、API設計の試行錯誤が行われていました。time
パッケージのTime
構造体の各フィールド(year
, month
, day
, hour
, minute
, second
, weekday
, zoneoffset
, zone
)は、元々小文字で始まっており、パッケージ外からは直接アクセスできない非公開の状態でした。
しかし、時間情報を扱うTime
構造体において、その内部要素(年、月、日など)に直接アクセスできることは、ユーザーが柔軟に時間データを操作したり、表示形式をカスタマイズしたりする上で非常に重要です。非公開のままでは、これらの情報にアクセスするためには、別途ゲッターメソッド(例: t.GetYear()
, t.GetMonth()
)を提供する必要があり、APIが冗長になる可能性があります。
この変更の背景には、Time
構造体の各要素をGo言語の慣習に則って直接アクセス可能にすることで、APIの使いやすさと直感性を向上させるという設計判断があったと考えられます。これにより、ユーザーはt.Year
、t.Month
のように直接フィールドにアクセスできるようになり、コードの記述が簡潔になります。
前提知識の解説
Go言語の可視性(Visibility)ルール
Go言語の可視性ルールは非常にシンプルで、識別子の最初の文字が大文字か小文字かによって決まります。
- Exported (公開): 識別子の最初の文字が大文字の場合、その識別子はパッケージ外からアクセス可能です。これは、他のプログラミング言語における
public
に相当します。例えば、fmt.Println
のPrintln
は公開されているため、fmt
パッケージをインポートすればどこからでも呼び出せます。構造体のフィールドが公開されている場合、myStruct.MyField
のように直接アクセスできます。 - Unexported (非公開): 識別子の最初の文字が小文字の場合、その識別子は定義されたパッケージ内からのみアクセス可能です。これは、他のプログラミング言語における
private
やinternal
に相当します。パッケージ外からは直接アクセスできません。
このルールは、API設計において非常に重要です。公開された識別子は、そのパッケージの外部インターフェースとなり、互換性を維持する責任が生じます。非公開の識別子は、パッケージの内部実装の詳細であり、外部からは見えないため、パッケージ開発者は自由に内部を変更できます。
Go言語のtime
パッケージ
Go言語の標準ライブラリには、日付と時刻を扱うためのtime
パッケージが用意されています。このパッケージは、時間の測定、表示、フォーマット、解析、および時間帯の処理など、幅広い機能を提供します。
time.Time
構造体:time
パッケージの中心となる型で、特定の時点(インスタント)を表します。この構造体は、年、月、日、時、分、秒、ナノ秒、タイムゾーン情報などを内部に保持しています。- 時間の表現:
time.Time
は、通常、協定世界時(UTC)または特定のロケーション(タイムゾーン)における時刻を表します。 - 時間の操作:
time.Time
オブジェクトは、加算(Add
)、減算(Sub
)、比較(Before
,After
,Equal
)などのメソッドを提供し、時間の計算や比較を容易にします。 - フォーマットと解析:
Format
メソッドとParse
関数を使用して、時刻を文字列に変換したり、文字列から時刻を解析したりできます。
このコミットは、time.Time
構造体の内部フィールドを公開することで、ユーザーがより直接的に時間要素にアクセスできるようにし、time
パッケージの利便性を高めることを目的としています。
技術的詳細
このコミットの技術的な核心は、Go言語の可視性ルールをtime.Time
構造体のフィールドに適用した点にあります。
-
フィールド名の変更:
year
->Year
month
->Month
day
->Day
hour
->Hour
minute
->Minute
second
->Second
weekday
->Weekday
zoneoffset
->ZoneOffset
zone
->Zone
これらの変更により、
Time
構造体のインスタンスt
がある場合、以前はt.year
のようにアクセスしようとするとコンパイルエラーになっていましたが、変更後はt.Year
のように直接アクセスできるようになります。 -
内部実装の更新:
src/lib/time/time.go
内のSecondsToUTC
,SecondsToLocalTime
,Seconds
,_Format
などの関数やメソッドは、Time
構造体のフィールドにアクセスする際に、新しい公開フィールド名を使用するように修正されています。例えば、t.hour
はt.Hour
に、t.weekday
はt.Weekday
に変更されています。これは、フィールド名が変更されたため、そのフィールドを参照するすべての箇所を更新する必要があるためです。 -
テストコードの更新:
src/lib/time/time_test.go
内の_Same
関数は、2つのTime
オブジェクトが同じであるかを比較する際に、各フィールドを比較しています。この比較も、新しい公開フィールド名に合わせてt.year == u.year
からt.Year == u.Year
のように修正されています。これにより、テストが引き続き正しく機能することが保証されます。 -
Makefileの変更:
src/lib/Makefile
において、time.dirinstall
の依存関係にio.dirinstall
が追加されています。これは、time
パッケージがio
パッケージの機能に依存するようになったことを示唆しています。具体的な依存関係の詳細は、このコミットの差分からは直接読み取れませんが、Go言語の標準ライブラリは相互に依存し合っているため、このような依存関係の追加は一般的なことです。
この変更は、time
パッケージのAPI設計における重要なマイルストーンであり、Go言語の可視性ルールがどのように実際のライブラリ設計に適用されるかを示す良い例です。これにより、time.Time
オブジェクトの各要素へのアクセスがより直接的になり、Go言語の慣習に沿った自然なコード記述が可能になりました。
コアとなるコードの変更箇所
src/lib/time/time.go
Time
構造体の定義部分:
--- a/src/lib/time/time.go
+++ b/src/lib/time/time.go
@@ -38,12 +38,12 @@ const (
)
type Time struct {
- year int64; // 2008 is 2008
- month, day int; // Sep-17 is 9, 17
- hour, minute, second int; // 10:43:12 is 10, 43, 12
- weekday int; // Sunday = 0, Monday = 1, ...
- zoneoffset int; // seconds west of UTC
- zone string;
+ Year int64; // 2008 is 2008
+ Month, Day int; // Sep-17 is 9, 17
+ Hour, Minute, Second int; // 10:43:12 is 10, 43, 12
+ Weekday int; // Sunday = 0, Monday = 1, ...
+ ZoneOffset int; // seconds west of UTC
+ Zone string;
}
SecondsToUTC
関数内のフィールド参照:
--- a/src/lib/time/time.go
+++ b/src/lib/time/time.go
@@ -82,14 +82,14 @@ func SecondsToUTC(sec int64) *Time {
}
// Time
- t.hour = int(sec/3600);
- t.minute = int((sec/60)%60);
- t.second = int(sec%60);
+ t.Hour = int(sec/3600);
+ t.Minute = int((sec/60)%60);
+ t.Second = int(sec%60);
// Day 0 = January 1, 1970 was a Thursday
- t.weekday = int((day + Thursday) % 7);
- if t.weekday < 0 {
- t.weekday += 7
+ t.Weekday = int((day + Thursday) % 7);
+ if t.Weekday < 0 {
+ t.Weekday += 7
}
// Change day from 0 = 1970 to 0 = 2001,
@@ -125,9 +125,9 @@ func SecondsToUTC(sec int64) *Time {
for m = 0; m < 12 && yday >= months[m]; m++ {
yday -= months[m]
}
- t.month = m+1;
- t.day = yday+1;
- t.zone = "GMT";
+ t.Month = m+1;
+ t.Day = yday+1;
+ t.Zone = "GMT";
SecondsToLocalTime
関数内のフィールド参照:
--- a/src/lib/time/time.go
+++ b/src/lib/time/time.go
@@ -154,8 +154,8 @@ func SecondsToLocalTime(sec int64) *Time {
return SecondsToUTC(sec)
}
t := SecondsToUTC(sec+int64(offset));
- t.zone = zone;
- t.zoneoffset = offset;
+ t.Zone = zone;
+ t.ZoneOffset = offset;
return t
}
Seconds
メソッド内のフィールド参照:
--- a/src/lib/time/time.go
+++ b/src/lib/time/time.go
@@ -172,7 +172,7 @@ func (t *Time) Seconds() int64 {
day := int64(0);
// Rewrite year to be >= 2001.
- year := t.year;
+ year := t.Year;
if year < 2001 {
n := (2001 - year)/400 + 1;
year += 400*n;
@@ -199,25 +199,25 @@ func (t *Time) Seconds() int64 {
day += 365*n;
// Add in days this year.
- months := months(t.year);
- for m := 0; m < t.month-1; m++ {
+ months := months(t.Year);
+ for m := 0; m < t.Month-1; m++ {
day += int64(months[m])
}
- day += int64(t.day - 1);
+ day += int64(t.Day - 1);
// Convert days to seconds since January 1, 2001.
sec := day * _SecondsPerDay;
// Add in time elapsed today.
- sec += int64(t.hour) * 3600;
- sec += int64(t.minute) * 60;
- sec += int64(t.second);
+ sec += int64(t.Hour) * 3600;
+ sec += int64(t.Minute) * 60;
+ sec += int64(t.Second);
// Convert from seconds since 2001 to seconds since 1970.
sec += _Days1970To2001 * _SecondsPerDay;
// Account for local time zone.
- sec -= int64(t.zoneoffset);
+ sec -= int64(t.ZoneOffset);
return sec
}
_Format
関数内のフィールド参照:
--- a/src/lib/time/time.go
+++ b/src/lib/time/time.go
@@ -289,39 +289,39 @@ func _Format(t *Time, fmt string) string {
i++;
switch fmt[i] {
case 'A': // %A full weekday name
- bp = _AddString(buf, bp, _LongDayNames[t.weekday]);
+ bp = _AddString(buf, bp, _LongDayNames[t.Weekday]);
case 'a': // %a abbreviated weekday name
- bp = _AddString(buf, bp, _ShortDayNames[t.weekday]);
+ bp = _AddString(buf, bp, _ShortDayNames[t.Weekday]);
case 'b': // %b abbreviated month name
- bp = _AddString(buf, bp, _ShortMonthNames[t.month-1]);
+ bp = _AddString(buf, bp, _ShortMonthNames[t.Month-1]);
case 'd': // %d day of month (01-31)
- _Decimal(buf[bp:bp+2], t.day);
+ _Decimal(buf[bp:bp+2], t.Day);
bp += 2;
case 'e': // %e day of month ( 1-31)
- if t.day >= 10 {
- _Decimal(buf[bp:bp+2], t.day)
+ if t.Day >= 10 {
+ _Decimal(buf[bp:bp+2], t.Day)
} else {
buf[bp] = ' ';
- buf[bp+1] = byte(t.day + '0')
+ buf[bp+1] = byte(t.Day + '0')
}
bp += 2;
case 'H': // %H hour 00-23
- _Decimal(buf[bp:bp+2], t.hour);
+ _Decimal(buf[bp:bp+2], t.Hour);
bp += 2;
case 'M': // %M minute 00-59
- _Decimal(buf[bp:bp+2], t.minute);
+ _Decimal(buf[bp:bp+2], t.Minute);
bp += 2;
case 'S': // %S second 00-59
- _Decimal(buf[bp:bp+2], t.second);
+ _Decimal(buf[bp:bp+2], t.Second);
bp += 2;
case 'Y': // %Y year 2008
- _Decimal(buf[bp:bp+4], int(t.year));
+ _Decimal(buf[bp:bp+4], int(t.Year));
bp += 4;
case 'y': // %y year 08
- _Decimal(buf[bp:bp+2], int(t.year%100));
+ _Decimal(buf[bp:bp+2], int(t.Year%100));
bp += 2;
case 'Z':
- bp = _AddString(buf, bp, t.zone);
+ bp = _AddString(buf, bp, t.Zone);
default:
buf[bp] = '%';
buf[bp+1] = fmt[i];
src/lib/time/time_test.go
_Same
関数内のフィールド比較:
--- a/src/lib/time/time_test.go
+++ b/src/lib/time/time_test.go
@@ -30,15 +30,15 @@ var localtests = []_TimeTest {
}
func _Same(t, u *Time) bool {
- return t.year == u.year
- && t.month == u.month
- && t.day == u.day
- && t.hour == u.hour
- && t.minute == u.minute
- && t.second == u.second
- && t.weekday == u.weekday
- && t.zoneoffset == u.zoneoffset
- && t.zone == u.zone
+ return t.Year == u.Year
+ && t.Month == u.Month
+ && t.Day == u.Day
+ && t.Hour == u.Hour
+ && t.Minute == u.Minute
+ && t.Second == u.Second
+ && t.Weekday == u.Weekday
+ && t.ZoneOffset == u.ZoneOffset
+ && t.Zone == u.Zone
}
コアとなるコードの解説
このコミットの主要な変更は、src/lib/time/time.go
ファイル内のTime
構造体の定義と、その構造体のフィールドを参照するすべてのコード箇所にあります。
-
Time
構造体のフィールド名の変更: 最も重要な変更は、Time
構造体の各フィールド名が小文字から大文字に変更されたことです。 例:year
->Year
,month
->Month
,hour
->Hour
など。 Go言語の可視性ルールにより、これによりこれらのフィールドはパッケージ外から直接アクセス可能な「公開(exported)」フィールドとなりました。これは、time.Time
オブジェクトの各時間要素(年、月、日など)に、myTime.Year
やmyTime.Month
のように直接アクセスできるようになったことを意味します。以前は、これらのフィールドは非公開であったため、パッケージ外からアクセスするには、別途ゲッターメソッド(例:myTime.GetYear()
)が必要でした。この変更により、APIの使いやすさと簡潔性が向上しました。 -
内部ロジックのフィールド参照の更新:
SecondsToUTC
,SecondsToLocalTime
,Seconds
,_Format
といったtime
パッケージ内の関数やメソッドは、Time
構造体のフィールドを操作しています。フィールド名が変更されたため、これらの関数やメソッド内のすべてのフィールド参照も、新しい大文字で始まる名前に更新されています。例えば、t.hour = int(sec/3600)
はt.Hour = int(sec/3600)
に変更されています。これは、コンパイルエラーを避けるために必須の変更です。 -
テストコードの更新:
src/lib/time/time_test.go
内の_Same
関数は、2つのTime
構造体が等しいかどうかを比較するために、そのすべてのフィールドを比較しています。この関数内のフィールド参照も、新しい公開フィールド名に合わせて更新されています。これにより、Time
構造体のフィールドが公開された後も、既存のテストが正しく機能し、変更が意図した通りであることを保証します。
これらの変更は、Go言語のAPI設計における重要な原則、すなわち「外部に公開するものは大文字で始める」という慣習に沿ったものです。これにより、time.Time
構造体はよりGo言語らしい、直感的で使いやすいAPIを提供できるようになりました。
関連リンク
参考にした情報源リンク
- Go言語の可視性ルール (Effective Go - Names)
- Go言語 time パッケージ公式ドキュメント
- Go言語の構造体とフィールドの可視性について (一般的なGo言語の可視性に関する情報源として参照)
- Go言語のtimeパッケージの使い方 (一般的なtimeパッケージの使い方に関する情報源として参照)
- Go言語の歴史と進化 (Go言語の初期開発に関する一般的な背景情報として参照)
- Go言語のコミット履歴 (Go言語のコミット履歴を辿る際の一般的な情報源として参照)