Fix time parsing and make tests deterministic
This commit is contained in:
		
							
								
								
									
										26
									
								
								taf.go
									
									
									
									
									
								
							
							
						
						
									
										26
									
								
								taf.go
									
									
									
									
									
								
							@@ -50,6 +50,14 @@ type Options struct {
 | 
				
			|||||||
	// If this is set, all speed units in the forecast will
 | 
						// If this is set, all speed units in the forecast will
 | 
				
			||||||
	// be converted to the given unit
 | 
						// be converted to the given unit
 | 
				
			||||||
	SpeedUnit units.Speed
 | 
						SpeedUnit units.Speed
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// The Year field is used to calculate the full date that this
 | 
				
			||||||
 | 
						// report was published. If it's unset, the current year will be used.
 | 
				
			||||||
 | 
						Year int
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// The Month field is used to calculate the full date that this
 | 
				
			||||||
 | 
						// report was published. If it's unset, the current year will be used.
 | 
				
			||||||
 | 
						Month time.Month
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// ParseWithOptions parses the data in a reader and returns a Forecast
 | 
					// ParseWithOptions parses the data in a reader and returns a Forecast
 | 
				
			||||||
@@ -67,6 +75,14 @@ func ParseWithOptions(r io.Reader, opts Options) (*Forecast, error) {
 | 
				
			|||||||
		filename = "string"
 | 
							filename = "string"
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if opts.Year == 0 {
 | 
				
			||||||
 | 
							opts.Year = time.Now().Year()
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if opts.Month == 0 {
 | 
				
			||||||
 | 
							opts.Month = time.Now().Month()
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ast, err := parser.Parser.Parse(filename, r)
 | 
						ast, err := parser.Parser.Parse(filename, r)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
@@ -83,7 +99,7 @@ func ParseWithOptions(r io.Reader, opts Options) (*Forecast, error) {
 | 
				
			|||||||
				fc.Airport = a
 | 
									fc.Airport = a
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		case item.Time != nil:
 | 
							case item.Time != nil:
 | 
				
			||||||
			t, err := parseTime(*item.Time)
 | 
								t, err := parseTime(*item.Time, opts.Month, opts.Year)
 | 
				
			||||||
			if err != nil {
 | 
								if err != nil {
 | 
				
			||||||
				return nil, participle.Errorf(item.Pos, "time: %s", err)
 | 
									return nil, participle.Errorf(item.Pos, "time: %s", err)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
@@ -91,7 +107,7 @@ func ParseWithOptions(r io.Reader, opts Options) (*Forecast, error) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
			// The Time item always comes with a Valid as well because
 | 
								// The Time item always comes with a Valid as well because
 | 
				
			||||||
			// of the way it's parsed into the AST
 | 
								// of the way it's parsed into the AST
 | 
				
			||||||
			vp, err := parseValid(item.Valid)
 | 
								vp, err := parseValid(item.Valid, opts.Month, opts.Year)
 | 
				
			||||||
			if err != nil {
 | 
								if err != nil {
 | 
				
			||||||
				return nil, participle.Errorf(item.Pos, "time: %s", err)
 | 
									return nil, participle.Errorf(item.Pos, "time: %s", err)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
@@ -125,7 +141,7 @@ func ParseWithOptions(r io.Reader, opts Options) (*Forecast, error) {
 | 
				
			|||||||
				CloudType: convertCloudType(item.SkyCondition.CloudType),
 | 
									CloudType: convertCloudType(item.SkyCondition.CloudType),
 | 
				
			||||||
			})
 | 
								})
 | 
				
			||||||
		case item.Temperature != nil:
 | 
							case item.Temperature != nil:
 | 
				
			||||||
			vt, err := parseValidTime(item.Temperature.Time)
 | 
								vt, err := parseValidTime(item.Temperature.Time, opts.Month, opts.Year)
 | 
				
			||||||
			if err != nil {
 | 
								if err != nil {
 | 
				
			||||||
				return nil, participle.Errorf(item.Temperature.Pos, "temp: %s", err)
 | 
									return nil, participle.Errorf(item.Temperature.Pos, "temp: %s", err)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
@@ -277,13 +293,13 @@ func ParseWithOptions(r io.Reader, opts Options) (*Forecast, error) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
			// FM changes don't have a valid pair, they only come with a single time string
 | 
								// FM changes don't have a valid pair, they only come with a single time string
 | 
				
			||||||
			if ch.Type == From {
 | 
								if ch.Type == From {
 | 
				
			||||||
				t, err := parseTime(item.Change.Time)
 | 
									t, err := parseTime(item.Change.Time, opts.Month, opts.Year)
 | 
				
			||||||
				if err != nil {
 | 
									if err != nil {
 | 
				
			||||||
					return nil, participle.Errorf(item.Change.Pos, "changes: %s", err)
 | 
										return nil, participle.Errorf(item.Change.Pos, "changes: %s", err)
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				ch.Valid = ValidPair{From: t}
 | 
									ch.Valid = ValidPair{From: t}
 | 
				
			||||||
			} else {
 | 
								} else {
 | 
				
			||||||
				vp, err := parseValid(item.Change.Valid)
 | 
									vp, err := parseValid(item.Change.Valid, opts.Month, opts.Year)
 | 
				
			||||||
				if err != nil {
 | 
									if err != nil {
 | 
				
			||||||
					return nil, participle.Errorf(item.Change.Pos, "changes: %s", err)
 | 
										return nil, participle.Errorf(item.Change.Pos, "changes: %s", err)
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										129
									
								
								taf_test.go
									
									
									
									
									
								
							
							
						
						
									
										129
									
								
								taf_test.go
									
									
									
									
									
								
							@@ -32,10 +32,10 @@ func TestKLAX(t *testing.T) {
 | 
				
			|||||||
			Longitude: -118.4079971,
 | 
								Longitude: -118.4079971,
 | 
				
			||||||
			Timezone:  "America/Los_Angeles",
 | 
								Timezone:  "America/Los_Angeles",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		PublishTime: time.Date(2023, time.September, 21, 20, 11, 0, 0, time.UTC),
 | 
							PublishTime: time.Date(2023, time.August, 21, 20, 11, 0, 0, time.UTC),
 | 
				
			||||||
		Valid: ValidPair{
 | 
							Valid: ValidPair{
 | 
				
			||||||
			From:     time.Date(2023, time.September, 21, 20, 0, 0, 0, time.UTC),
 | 
								From:     time.Date(2023, time.August, 21, 20, 0, 0, 0, time.UTC),
 | 
				
			||||||
			To:       time.Date(2023, time.September, 23, 0, 0, 0, 0, time.UTC),
 | 
								To:       time.Date(2023, time.August, 23, 0, 0, 0, 0, time.UTC),
 | 
				
			||||||
			Duration: time.Duration(100800000000000),
 | 
								Duration: time.Duration(100800000000000),
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		Visibility: Visibility{
 | 
							Visibility: Visibility{
 | 
				
			||||||
@@ -68,7 +68,7 @@ func TestKLAX(t *testing.T) {
 | 
				
			|||||||
			{
 | 
								{
 | 
				
			||||||
				Type: From,
 | 
									Type: From,
 | 
				
			||||||
				Valid: ValidPair{
 | 
									Valid: ValidPair{
 | 
				
			||||||
					From: time.Date(2023, time.September, 21, 22, 0, 0, 0, time.UTC),
 | 
										From: time.Date(2023, time.August, 21, 22, 0, 0, 0, time.UTC),
 | 
				
			||||||
				},
 | 
									},
 | 
				
			||||||
				Visibility: Visibility{
 | 
									Visibility: Visibility{
 | 
				
			||||||
					Plus:  true,
 | 
										Plus:  true,
 | 
				
			||||||
@@ -92,7 +92,7 @@ func TestKLAX(t *testing.T) {
 | 
				
			|||||||
			{
 | 
								{
 | 
				
			||||||
				Type: From,
 | 
									Type: From,
 | 
				
			||||||
				Valid: ValidPair{
 | 
									Valid: ValidPair{
 | 
				
			||||||
					From: time.Date(2023, time.September, 22, 3, 0, 0, 0, time.UTC),
 | 
										From: time.Date(2023, time.August, 22, 3, 0, 0, 0, time.UTC),
 | 
				
			||||||
				},
 | 
									},
 | 
				
			||||||
				Visibility: Visibility{
 | 
									Visibility: Visibility{
 | 
				
			||||||
					Plus:  true,
 | 
										Plus:  true,
 | 
				
			||||||
@@ -116,7 +116,7 @@ func TestKLAX(t *testing.T) {
 | 
				
			|||||||
			{
 | 
								{
 | 
				
			||||||
				Type: From,
 | 
									Type: From,
 | 
				
			||||||
				Valid: ValidPair{
 | 
									Valid: ValidPair{
 | 
				
			||||||
					From: time.Date(2023, time.September, 22, 10, 0, 0, 0, time.UTC),
 | 
										From: time.Date(2023, time.August, 22, 10, 0, 0, 0, time.UTC),
 | 
				
			||||||
				},
 | 
									},
 | 
				
			||||||
				Visibility: Visibility{
 | 
									Visibility: Visibility{
 | 
				
			||||||
					Plus:  true,
 | 
										Plus:  true,
 | 
				
			||||||
@@ -140,7 +140,7 @@ func TestKLAX(t *testing.T) {
 | 
				
			|||||||
			{
 | 
								{
 | 
				
			||||||
				Type: From,
 | 
									Type: From,
 | 
				
			||||||
				Valid: ValidPair{
 | 
									Valid: ValidPair{
 | 
				
			||||||
					From: time.Date(2023, time.September, 22, 17, 0, 0, 0, time.UTC),
 | 
										From: time.Date(2023, time.August, 22, 17, 0, 0, 0, time.UTC),
 | 
				
			||||||
				},
 | 
									},
 | 
				
			||||||
				Visibility: Visibility{
 | 
									Visibility: Visibility{
 | 
				
			||||||
					Plus:  true,
 | 
										Plus:  true,
 | 
				
			||||||
@@ -164,7 +164,7 @@ func TestKLAX(t *testing.T) {
 | 
				
			|||||||
			{
 | 
								{
 | 
				
			||||||
				Type: From,
 | 
									Type: From,
 | 
				
			||||||
				Valid: ValidPair{
 | 
									Valid: ValidPair{
 | 
				
			||||||
					From: time.Date(2023, time.September, 22, 20, 0, 0, 0, time.UTC),
 | 
										From: time.Date(2023, time.August, 22, 20, 0, 0, 0, time.UTC),
 | 
				
			||||||
				},
 | 
									},
 | 
				
			||||||
				Visibility: Visibility{
 | 
									Visibility: Visibility{
 | 
				
			||||||
					Plus:  true,
 | 
										Plus:  true,
 | 
				
			||||||
@@ -188,7 +188,10 @@ func TestKLAX(t *testing.T) {
 | 
				
			|||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fc, err := Parse(strings.NewReader(data))
 | 
						fc, err := ParseWithOptions(strings.NewReader(data), Options{
 | 
				
			||||||
 | 
							Month: time.August,
 | 
				
			||||||
 | 
							Year:  2023,
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		t.Fatalf("Error during parsing: %s", err)
 | 
							t.Fatalf("Error during parsing: %s", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -217,10 +220,10 @@ func TestZGSZ(t *testing.T) {
 | 
				
			|||||||
			Longitude: 113.8109970093,
 | 
								Longitude: 113.8109970093,
 | 
				
			||||||
			Timezone:  "Asia/Shanghai",
 | 
								Timezone:  "Asia/Shanghai",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		PublishTime: time.Date(2023, time.September, 21, 19, 7, 0, 0, time.UTC),
 | 
							PublishTime: time.Date(2023, time.August, 21, 19, 7, 0, 0, time.UTC),
 | 
				
			||||||
		Valid: ValidPair{
 | 
							Valid: ValidPair{
 | 
				
			||||||
			From:     time.Date(2023, time.September, 21, 18, 0, 0, 0, time.UTC),
 | 
								From:     time.Date(2023, time.August, 21, 18, 0, 0, 0, time.UTC),
 | 
				
			||||||
			To:       time.Date(2023, time.September, 22, 18, 0, 0, 0, time.UTC),
 | 
								To:       time.Date(2023, time.August, 22, 18, 0, 0, 0, time.UTC),
 | 
				
			||||||
			Duration: time.Duration(86400000000000),
 | 
								Duration: time.Duration(86400000000000),
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		Visibility: Visibility{
 | 
							Visibility: Visibility{
 | 
				
			||||||
@@ -244,20 +247,20 @@ func TestZGSZ(t *testing.T) {
 | 
				
			|||||||
			{
 | 
								{
 | 
				
			||||||
				Type:  High,
 | 
									Type:  High,
 | 
				
			||||||
				Value: 32,
 | 
									Value: 32,
 | 
				
			||||||
				Time:  time.Date(2023, time.September, 22, 6, 0, 0, 0, time.UTC),
 | 
									Time:  time.Date(2023, time.August, 22, 6, 0, 0, 0, time.UTC),
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				Type:  Low,
 | 
									Type:  Low,
 | 
				
			||||||
				Value: 28,
 | 
									Value: 28,
 | 
				
			||||||
				Time:  time.Date(2023, time.September, 21, 22, 0, 0, 0, time.UTC),
 | 
									Time:  time.Date(2023, time.August, 21, 22, 0, 0, 0, time.UTC),
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		Changes: []*Change{
 | 
							Changes: []*Change{
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				Type: Temporary,
 | 
									Type: Temporary,
 | 
				
			||||||
				Valid: ValidPair{
 | 
									Valid: ValidPair{
 | 
				
			||||||
					From:     time.Date(2023, time.September, 21, 20, 0, 0, 0, time.UTC),
 | 
										From:     time.Date(2023, time.August, 21, 20, 0, 0, 0, time.UTC),
 | 
				
			||||||
					To:       time.Date(2023, time.September, 22, 2, 0, 0, 0, time.UTC),
 | 
										To:       time.Date(2023, time.August, 22, 2, 0, 0, 0, time.UTC),
 | 
				
			||||||
					Duration: time.Duration(21600000000000),
 | 
										Duration: time.Duration(21600000000000),
 | 
				
			||||||
				},
 | 
									},
 | 
				
			||||||
				SkyCondition: []SkyCondition{
 | 
									SkyCondition: []SkyCondition{
 | 
				
			||||||
@@ -281,8 +284,8 @@ func TestZGSZ(t *testing.T) {
 | 
				
			|||||||
			{
 | 
								{
 | 
				
			||||||
				Type: Temporary,
 | 
									Type: Temporary,
 | 
				
			||||||
				Valid: ValidPair{
 | 
									Valid: ValidPair{
 | 
				
			||||||
					From:     time.Date(2023, time.September, 22, 4, 0, 0, 0, time.UTC),
 | 
										From:     time.Date(2023, time.August, 22, 4, 0, 0, 0, time.UTC),
 | 
				
			||||||
					To:       time.Date(2023, time.September, 22, 8, 0, 0, 0, time.UTC),
 | 
										To:       time.Date(2023, time.August, 22, 8, 0, 0, 0, time.UTC),
 | 
				
			||||||
					Duration: time.Duration(14400000000000),
 | 
										Duration: time.Duration(14400000000000),
 | 
				
			||||||
				},
 | 
									},
 | 
				
			||||||
				SkyCondition: []SkyCondition{
 | 
									SkyCondition: []SkyCondition{
 | 
				
			||||||
@@ -306,7 +309,10 @@ func TestZGSZ(t *testing.T) {
 | 
				
			|||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fc, err := Parse(strings.NewReader(data))
 | 
						fc, err := ParseWithOptions(strings.NewReader(data), Options{
 | 
				
			||||||
 | 
							Month: time.August,
 | 
				
			||||||
 | 
							Year:  2023,
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		t.Fatalf("Error during parsing: %s", err)
 | 
							t.Fatalf("Error during parsing: %s", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -337,10 +343,10 @@ func TestLFBD(t *testing.T) {
 | 
				
			|||||||
			Longitude: -0.7155560255,
 | 
								Longitude: -0.7155560255,
 | 
				
			||||||
			Timezone:  "Europe/Paris",
 | 
								Timezone:  "Europe/Paris",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		PublishTime: time.Date(2023, time.September, 21, 17, 0, 0, 0, time.UTC),
 | 
							PublishTime: time.Date(2023, time.August, 21, 17, 0, 0, 0, time.UTC),
 | 
				
			||||||
		Valid: ValidPair{
 | 
							Valid: ValidPair{
 | 
				
			||||||
			From:     time.Date(2023, time.September, 21, 18, 0, 0, 0, time.UTC),
 | 
								From:     time.Date(2023, time.August, 21, 18, 0, 0, 0, time.UTC),
 | 
				
			||||||
			To:       time.Date(2023, time.September, 23, 0, 0, 0, 0, time.UTC),
 | 
								To:       time.Date(2023, time.August, 23, 0, 0, 0, 0, time.UTC),
 | 
				
			||||||
			Duration: time.Duration(108000000000000),
 | 
								Duration: time.Duration(108000000000000),
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		Wind: Wind{
 | 
							Wind: Wind{
 | 
				
			||||||
@@ -354,20 +360,20 @@ func TestLFBD(t *testing.T) {
 | 
				
			|||||||
			{
 | 
								{
 | 
				
			||||||
				Type:  High,
 | 
									Type:  High,
 | 
				
			||||||
				Value: 37,
 | 
									Value: 37,
 | 
				
			||||||
				Time:  time.Date(2023, time.September, 22, 14, 0, 0, 0, time.UTC),
 | 
									Time:  time.Date(2023, time.August, 22, 14, 0, 0, 0, time.UTC),
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				Type:  Low,
 | 
									Type:  Low,
 | 
				
			||||||
				Value: 22,
 | 
									Value: 22,
 | 
				
			||||||
				Time:  time.Date(2023, time.September, 22, 5, 0, 0, 0, time.UTC),
 | 
									Time:  time.Date(2023, time.August, 22, 5, 0, 0, 0, time.UTC),
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		Changes: []*Change{
 | 
							Changes: []*Change{
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				Type: Becoming,
 | 
									Type: Becoming,
 | 
				
			||||||
				Valid: ValidPair{
 | 
									Valid: ValidPair{
 | 
				
			||||||
					From:     time.Date(2023, time.September, 21, 18, 0, 0, 0, time.UTC),
 | 
										From:     time.Date(2023, time.August, 21, 18, 0, 0, 0, time.UTC),
 | 
				
			||||||
					To:       time.Date(2023, time.September, 21, 20, 0, 0, 0, time.UTC),
 | 
										To:       time.Date(2023, time.August, 21, 20, 0, 0, 0, time.UTC),
 | 
				
			||||||
					Duration: time.Duration(7200000000000),
 | 
										Duration: time.Duration(7200000000000),
 | 
				
			||||||
				},
 | 
									},
 | 
				
			||||||
				Wind: Wind{
 | 
									Wind: Wind{
 | 
				
			||||||
@@ -381,8 +387,8 @@ func TestLFBD(t *testing.T) {
 | 
				
			|||||||
			{
 | 
								{
 | 
				
			||||||
				Type: Becoming,
 | 
									Type: Becoming,
 | 
				
			||||||
				Valid: ValidPair{
 | 
									Valid: ValidPair{
 | 
				
			||||||
					From:     time.Date(2023, time.September, 22, 0, 0, 0, 0, time.UTC),
 | 
										From:     time.Date(2023, time.August, 22, 0, 0, 0, 0, time.UTC),
 | 
				
			||||||
					To:       time.Date(2023, time.September, 22, 2, 0, 0, 0, time.UTC),
 | 
										To:       time.Date(2023, time.August, 22, 2, 0, 0, 0, time.UTC),
 | 
				
			||||||
					Duration: time.Duration(7200000000000),
 | 
										Duration: time.Duration(7200000000000),
 | 
				
			||||||
				},
 | 
									},
 | 
				
			||||||
				Wind: Wind{
 | 
									Wind: Wind{
 | 
				
			||||||
@@ -396,8 +402,8 @@ func TestLFBD(t *testing.T) {
 | 
				
			|||||||
			{
 | 
								{
 | 
				
			||||||
				Type: Becoming,
 | 
									Type: Becoming,
 | 
				
			||||||
				Valid: ValidPair{
 | 
									Valid: ValidPair{
 | 
				
			||||||
					From:     time.Date(2023, time.September, 22, 13, 0, 0, 0, time.UTC),
 | 
										From:     time.Date(2023, time.August, 22, 13, 0, 0, 0, time.UTC),
 | 
				
			||||||
					To:       time.Date(2023, time.September, 22, 15, 0, 0, 0, time.UTC),
 | 
										To:       time.Date(2023, time.August, 22, 15, 0, 0, 0, time.UTC),
 | 
				
			||||||
					Duration: time.Duration(7200000000000),
 | 
										Duration: time.Duration(7200000000000),
 | 
				
			||||||
				},
 | 
									},
 | 
				
			||||||
				Wind: Wind{
 | 
									Wind: Wind{
 | 
				
			||||||
@@ -411,8 +417,8 @@ func TestLFBD(t *testing.T) {
 | 
				
			|||||||
			{
 | 
								{
 | 
				
			||||||
				Type: Becoming,
 | 
									Type: Becoming,
 | 
				
			||||||
				Valid: ValidPair{
 | 
									Valid: ValidPair{
 | 
				
			||||||
					From:     time.Date(2023, time.September, 22, 22, 0, 0, 0, time.UTC),
 | 
										From:     time.Date(2023, time.August, 22, 22, 0, 0, 0, time.UTC),
 | 
				
			||||||
					To:       time.Date(2023, time.September, 23, 0, 0, 0, 0, time.UTC),
 | 
										To:       time.Date(2023, time.August, 23, 0, 0, 0, 0, time.UTC),
 | 
				
			||||||
					Duration: time.Duration(7200000000000),
 | 
										Duration: time.Duration(7200000000000),
 | 
				
			||||||
				},
 | 
									},
 | 
				
			||||||
				Wind: Wind{
 | 
									Wind: Wind{
 | 
				
			||||||
@@ -429,7 +435,10 @@ func TestLFBD(t *testing.T) {
 | 
				
			|||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fc, err := Parse(strings.NewReader(data))
 | 
						fc, err := ParseWithOptions(strings.NewReader(data), Options{
 | 
				
			||||||
 | 
							Month: time.August,
 | 
				
			||||||
 | 
							Year:  2023,
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		t.Fatalf("Error during parsing: %s", err)
 | 
							t.Fatalf("Error during parsing: %s", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -462,10 +471,10 @@ func TestUUEE(t *testing.T) {
 | 
				
			|||||||
			Longitude: 37.4146003723,
 | 
								Longitude: 37.4146003723,
 | 
				
			||||||
			Timezone:  "Europe/Moscow",
 | 
								Timezone:  "Europe/Moscow",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		PublishTime: time.Date(2023, time.September, 21, 19, 58, 0, 0, time.UTC),
 | 
							PublishTime: time.Date(2023, time.August, 21, 19, 58, 0, 0, time.UTC),
 | 
				
			||||||
		Valid: ValidPair{
 | 
							Valid: ValidPair{
 | 
				
			||||||
			From:     time.Date(2023, time.September, 21, 21, 0, 0, 0, time.UTC),
 | 
								From:     time.Date(2023, time.August, 21, 21, 0, 0, 0, time.UTC),
 | 
				
			||||||
			To:       time.Date(2023, time.September, 22, 21, 0, 0, 0, time.UTC),
 | 
								To:       time.Date(2023, time.August, 22, 21, 0, 0, 0, time.UTC),
 | 
				
			||||||
			Duration: time.Duration(86400000000000),
 | 
								Duration: time.Duration(86400000000000),
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		Visibility: Visibility{
 | 
							Visibility: Visibility{
 | 
				
			||||||
@@ -489,20 +498,20 @@ func TestUUEE(t *testing.T) {
 | 
				
			|||||||
			{
 | 
								{
 | 
				
			||||||
				Type:  High,
 | 
									Type:  High,
 | 
				
			||||||
				Value: 20,
 | 
									Value: 20,
 | 
				
			||||||
				Time:  time.Date(2023, time.September, 22, 12, 0, 0, 0, time.UTC),
 | 
									Time:  time.Date(2023, time.August, 22, 12, 0, 0, 0, time.UTC),
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				Type:  Low,
 | 
									Type:  Low,
 | 
				
			||||||
				Value: 12,
 | 
									Value: 12,
 | 
				
			||||||
				Time:  time.Date(2023, time.September, 22, 2, 0, 0, 0, time.UTC),
 | 
									Time:  time.Date(2023, time.August, 22, 2, 0, 0, 0, time.UTC),
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		Changes: []*Change{
 | 
							Changes: []*Change{
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				Type: Temporary,
 | 
									Type: Temporary,
 | 
				
			||||||
				Valid: ValidPair{
 | 
									Valid: ValidPair{
 | 
				
			||||||
					From:     time.Date(2023, time.September, 21, 21, 0, 0, 0, time.UTC),
 | 
										From:     time.Date(2023, time.August, 21, 21, 0, 0, 0, time.UTC),
 | 
				
			||||||
					To:       time.Date(2023, time.September, 22, 4, 0, 0, 0, time.UTC),
 | 
										To:       time.Date(2023, time.August, 22, 4, 0, 0, 0, time.UTC),
 | 
				
			||||||
					Duration: time.Duration(25200000000000),
 | 
										Duration: time.Duration(25200000000000),
 | 
				
			||||||
				},
 | 
									},
 | 
				
			||||||
				SkyCondition: []SkyCondition{
 | 
									SkyCondition: []SkyCondition{
 | 
				
			||||||
@@ -516,8 +525,8 @@ func TestUUEE(t *testing.T) {
 | 
				
			|||||||
			{
 | 
								{
 | 
				
			||||||
				Type: Temporary,
 | 
									Type: Temporary,
 | 
				
			||||||
				Valid: ValidPair{
 | 
									Valid: ValidPair{
 | 
				
			||||||
					From:     time.Date(2023, time.September, 21, 21, 0, 0, 0, time.UTC),
 | 
										From:     time.Date(2023, time.August, 21, 21, 0, 0, 0, time.UTC),
 | 
				
			||||||
					To:       time.Date(2023, time.September, 22, 4, 0, 0, 0, time.UTC),
 | 
										To:       time.Date(2023, time.August, 22, 4, 0, 0, 0, time.UTC),
 | 
				
			||||||
					Duration: time.Duration(25200000000000),
 | 
										Duration: time.Duration(25200000000000),
 | 
				
			||||||
				},
 | 
									},
 | 
				
			||||||
				Visibility: Visibility{
 | 
									Visibility: Visibility{
 | 
				
			||||||
@@ -533,8 +542,8 @@ func TestUUEE(t *testing.T) {
 | 
				
			|||||||
			{
 | 
								{
 | 
				
			||||||
				Type: Becoming,
 | 
									Type: Becoming,
 | 
				
			||||||
				Valid: ValidPair{
 | 
									Valid: ValidPair{
 | 
				
			||||||
					From:     time.Date(2023, time.September, 22, 4, 0, 0, 0, time.UTC),
 | 
										From:     time.Date(2023, time.August, 22, 4, 0, 0, 0, time.UTC),
 | 
				
			||||||
					To:       time.Date(2023, time.September, 22, 6, 0, 0, 0, time.UTC),
 | 
										To:       time.Date(2023, time.August, 22, 6, 0, 0, 0, time.UTC),
 | 
				
			||||||
					Duration: time.Duration(7200000000000),
 | 
										Duration: time.Duration(7200000000000),
 | 
				
			||||||
				},
 | 
									},
 | 
				
			||||||
				Wind: Wind{
 | 
									Wind: Wind{
 | 
				
			||||||
@@ -549,8 +558,8 @@ func TestUUEE(t *testing.T) {
 | 
				
			|||||||
			{
 | 
								{
 | 
				
			||||||
				Type: Temporary,
 | 
									Type: Temporary,
 | 
				
			||||||
				Valid: ValidPair{
 | 
									Valid: ValidPair{
 | 
				
			||||||
					From:     time.Date(2023, time.September, 22, 9, 0, 0, 0, time.UTC),
 | 
										From:     time.Date(2023, time.August, 22, 9, 0, 0, 0, time.UTC),
 | 
				
			||||||
					To:       time.Date(2023, time.September, 22, 18, 0, 0, 0, time.UTC),
 | 
										To:       time.Date(2023, time.August, 22, 18, 0, 0, 0, time.UTC),
 | 
				
			||||||
					Duration: time.Duration(32400000000000),
 | 
										Duration: time.Duration(32400000000000),
 | 
				
			||||||
				},
 | 
									},
 | 
				
			||||||
				SkyCondition: []SkyCondition{
 | 
									SkyCondition: []SkyCondition{
 | 
				
			||||||
@@ -571,7 +580,10 @@ func TestUUEE(t *testing.T) {
 | 
				
			|||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fc, err := Parse(strings.NewReader(data))
 | 
						fc, err := ParseWithOptions(strings.NewReader(data), Options{
 | 
				
			||||||
 | 
							Month: time.August,
 | 
				
			||||||
 | 
							Year:  2023,
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		t.Fatalf("Error during parsing: %s", err)
 | 
							t.Fatalf("Error during parsing: %s", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -602,10 +614,10 @@ func TestEGLL(t *testing.T) {
 | 
				
			|||||||
			Longitude: -0.4619410038,
 | 
								Longitude: -0.4619410038,
 | 
				
			||||||
			Timezone:  "Europe/London",
 | 
								Timezone:  "Europe/London",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		PublishTime: time.Date(2023, time.September, 21, 16, 58, 0, 0, time.UTC),
 | 
							PublishTime: time.Date(2023, time.August, 21, 16, 58, 0, 0, time.UTC),
 | 
				
			||||||
		Valid: ValidPair{
 | 
							Valid: ValidPair{
 | 
				
			||||||
			From:     time.Date(2023, time.September, 21, 18, 0, 0, 0, time.UTC),
 | 
								From:     time.Date(2023, time.August, 21, 18, 0, 0, 0, time.UTC),
 | 
				
			||||||
			To:       time.Date(2023, time.September, 23, 0, 0, 0, 0, time.UTC),
 | 
								To:       time.Date(2023, time.August, 23, 0, 0, 0, 0, time.UTC),
 | 
				
			||||||
			Duration: time.Duration(108000000000000),
 | 
								Duration: time.Duration(108000000000000),
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		Visibility: Visibility{
 | 
							Visibility: Visibility{
 | 
				
			||||||
@@ -629,8 +641,8 @@ func TestEGLL(t *testing.T) {
 | 
				
			|||||||
			{
 | 
								{
 | 
				
			||||||
				Type: Becoming,
 | 
									Type: Becoming,
 | 
				
			||||||
				Valid: ValidPair{
 | 
									Valid: ValidPair{
 | 
				
			||||||
					From:     time.Date(2023, time.September, 22, 1, 0, 0, 0, time.UTC),
 | 
										From:     time.Date(2023, time.August, 22, 1, 0, 0, 0, time.UTC),
 | 
				
			||||||
					To:       time.Date(2023, time.September, 22, 4, 0, 0, 0, time.UTC),
 | 
										To:       time.Date(2023, time.August, 22, 4, 0, 0, 0, time.UTC),
 | 
				
			||||||
					Duration: time.Duration(10800000000000),
 | 
										Duration: time.Duration(10800000000000),
 | 
				
			||||||
				},
 | 
									},
 | 
				
			||||||
				SkyCondition: []SkyCondition{
 | 
									SkyCondition: []SkyCondition{
 | 
				
			||||||
@@ -644,8 +656,8 @@ func TestEGLL(t *testing.T) {
 | 
				
			|||||||
			{
 | 
								{
 | 
				
			||||||
				Type: Temporary,
 | 
									Type: Temporary,
 | 
				
			||||||
				Valid: ValidPair{
 | 
									Valid: ValidPair{
 | 
				
			||||||
					From:     time.Date(2023, time.September, 22, 2, 0, 0, 0, time.UTC),
 | 
										From:     time.Date(2023, time.August, 22, 2, 0, 0, 0, time.UTC),
 | 
				
			||||||
					To:       time.Date(2023, time.September, 22, 6, 0, 0, 0, time.UTC),
 | 
										To:       time.Date(2023, time.August, 22, 6, 0, 0, 0, time.UTC),
 | 
				
			||||||
					Duration: time.Duration(14400000000000),
 | 
										Duration: time.Duration(14400000000000),
 | 
				
			||||||
				},
 | 
									},
 | 
				
			||||||
				Visibility: Visibility{
 | 
									Visibility: Visibility{
 | 
				
			||||||
@@ -662,8 +674,8 @@ func TestEGLL(t *testing.T) {
 | 
				
			|||||||
			{
 | 
								{
 | 
				
			||||||
				Type: Becoming,
 | 
									Type: Becoming,
 | 
				
			||||||
				Valid: ValidPair{
 | 
									Valid: ValidPair{
 | 
				
			||||||
					From:     time.Date(2023, time.September, 22, 7, 0, 0, 0, time.UTC),
 | 
										From:     time.Date(2023, time.August, 22, 7, 0, 0, 0, time.UTC),
 | 
				
			||||||
					To:       time.Date(2023, time.September, 22, 10, 0, 0, 0, time.UTC),
 | 
										To:       time.Date(2023, time.August, 22, 10, 0, 0, 0, time.UTC),
 | 
				
			||||||
					Duration: time.Duration(10800000000000),
 | 
										Duration: time.Duration(10800000000000),
 | 
				
			||||||
				},
 | 
									},
 | 
				
			||||||
				SkyCondition: []SkyCondition{
 | 
									SkyCondition: []SkyCondition{
 | 
				
			||||||
@@ -676,7 +688,10 @@ func TestEGLL(t *testing.T) {
 | 
				
			|||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fc, err := Parse(strings.NewReader(data))
 | 
						fc, err := ParseWithOptions(strings.NewReader(data), Options{
 | 
				
			||||||
 | 
							Month: time.August,
 | 
				
			||||||
 | 
							Year:  2023,
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		t.Fatalf("Error during parsing: %s", err)
 | 
							t.Fatalf("Error during parsing: %s", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										16
									
								
								time.go
									
									
									
									
									
								
							
							
						
						
									
										16
									
								
								time.go
									
									
									
									
									
								
							@@ -12,22 +12,21 @@ const (
 | 
				
			|||||||
	ValidFormat = "0215"
 | 
						ValidFormat = "0215"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func parseTime(s string) (time.Time, error) {
 | 
					func parseTime(s string, m time.Month, year int) (time.Time, error) {
 | 
				
			||||||
	t, err := time.Parse(TimeFormat, s)
 | 
						t, err := time.Parse(TimeFormat, s)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return time.Time{}, err
 | 
							return time.Time{}, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	now := time.Now().UTC()
 | 
						return t.AddDate(year, int(m)-1, 0), nil
 | 
				
			||||||
	return t.AddDate(now.Year(), int(now.Month()), 0), nil
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func parseValid(v *parser.ValidPair) (ValidPair, error) {
 | 
					func parseValid(v *parser.ValidPair, m time.Month, year int) (ValidPair, error) {
 | 
				
			||||||
	start, err := parseValidTime(v.Start)
 | 
						start, err := parseValidTime(v.Start, m, year)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return ValidPair{}, err
 | 
							return ValidPair{}, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	end, err := parseValidTime(v.End)
 | 
						end, err := parseValidTime(v.End, m, year)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return ValidPair{}, err
 | 
							return ValidPair{}, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -39,7 +38,7 @@ func parseValid(v *parser.ValidPair) (ValidPair, error) {
 | 
				
			|||||||
	}, nil
 | 
						}, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func parseValidTime(s string) (time.Time, error) {
 | 
					func parseValidTime(s string, m time.Month, year int) (time.Time, error) {
 | 
				
			||||||
	addDays := 0
 | 
						addDays := 0
 | 
				
			||||||
	// Go doesn't know what to do with hour 24,
 | 
						// Go doesn't know what to do with hour 24,
 | 
				
			||||||
	// so we set it to 00 the next day
 | 
						// so we set it to 00 the next day
 | 
				
			||||||
@@ -53,6 +52,5 @@ func parseValidTime(s string) (time.Time, error) {
 | 
				
			|||||||
		return time.Time{}, err
 | 
							return time.Time{}, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	now := time.Now().UTC()
 | 
						return t.AddDate(year, int(m)-1, addDays), nil
 | 
				
			||||||
	return t.AddDate(now.Year(), int(now.Month()), addDays), nil
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user