gitee.com/curryzheng/dm@v0.0.1/i.go (about) 1 /* 2 * Copyright (c) 2000-2018, 达梦数据库有限公司. 3 * All rights reserved. 4 */ 5 package dm 6 7 import ( 8 "math" 9 "strconv" 10 "strings" 11 "time" 12 "unicode" 13 ) 14 15 func encodeByString(x string, dtype int, scale int, ltz int, dtz int) ([]byte, error) { 16 dt := make([]int, DT_LEN) 17 if _, err := toDTFromString(x, dt); err != nil { 18 return nil, err 19 } 20 return encode(dt, dtype, scale, ltz) 21 } 22 23 func encodeByTime(x time.Time, dtype int, scale int, lTz int, dbTz int) ([]byte, error) { 24 dt := toDTFromTime(x) 25 return encode(dt, dtype, scale, lTz) 26 } 27 28 func encodeByDateNumber(x int64, destDType int, scale int, lTz int, dbTz int16) ([]byte, error) { 29 switch destDType { 30 case DATETIME: 31 32 if x > 2958463*24*60*60 { 33 return nil, ECGO_DATETIME_OVERFLOW.throw() 34 } 35 36 dt := toDTFromUnix(x-Seconds_1900_1970, 0) 37 return encode(dt, destDType, scale, lTz) 38 39 case TIME: 40 dt := toDTFromUnix(x, 0) 41 return encode(dt, destDType, scale, lTz) 42 43 case DATE: 44 45 if x > 2958463 { 46 return nil, ECGO_DATETIME_OVERFLOW.throw() 47 } 48 49 dt := toDTFromUnix(x*24*60*60-Seconds_1900_1970, 0) 50 if dt[OFFSET_YEAR] < -4712 || dt[OFFSET_YEAR] > 9999 { 51 return nil, ECGO_DATETIME_OVERFLOW.throw() 52 } 53 return encode(dt, destDType, scale, lTz) 54 55 default: 56 return nil, ECGO_DATA_CONVERTION_ERROR.throw() 57 58 } 59 } 60 61 func toTimeFromString(str string, ltz int) time.Time { 62 dt := make([]int, DT_LEN) 63 toDTFromString(str, dt) 64 return toTimeFromDT(dt, ltz) 65 } 66 67 func toTimeFromDT(dt []int, ltz int) time.Time { 68 var year, month, day, hour, minute, second, nsec, tz int 69 70 year = dt[OFFSET_YEAR] 71 72 if dt[OFFSET_MONTH] > 0 { 73 month = dt[OFFSET_MONTH] 74 } else { 75 month = 1 76 } 77 78 if dt[OFFSET_DAY] > 0 { 79 day = dt[OFFSET_DAY] 80 } else { 81 day = 1 82 } 83 84 hour = dt[OFFSET_HOUR] 85 minute = dt[OFFSET_MINUTE] 86 second = dt[OFFSET_SECOND] 87 nsec = dt[OFFSET_MILLISECOND] * 1000 88 if dt[OFFSET_TIMEZONE] == INVALID_VALUE { 89 tz = ltz * 60 90 } else { 91 tz = dt[OFFSET_TIMEZONE] * 60 92 } 93 return time.Date(year, time.Month(month), day, hour, minute, second, nsec, time.FixedZone("", tz)) 94 } 95 96 func decode(value []byte, isBdta bool, colType int, scale int, ltz int, dbtz int) []int { 97 var dt []int 98 if isBdta { 99 dt = dmdtDecodeBdta(value) 100 } else { 101 dt = dmdtDecodeFast(value) 102 } 103 104 if isLocalTimeZone(colType, scale) { 105 transformTZ(dt, dbtz, ltz) 106 scale = getLocalTimeZoneScale(colType, scale) 107 } 108 109 if scale > 0 && scale < 6 { 110 tmp := math.Pow10(6 - scale) 111 dt[OFFSET_MILLISECOND] = int(float64(dt[OFFSET_MILLISECOND]) / tmp * tmp) 112 } 113 return dt 114 } 115 116 func dmdtDecodeFast(value []byte) []int { 117 dt := make([]int, DT_LEN) 118 dt[OFFSET_TIMEZONE] = INVALID_VALUE 119 120 if len(value) == 3 { 121 122 dt[OFFSET_YEAR] = int(Dm_build_1.Dm_build_98(value, 0)) & 0x7FFF 123 if dt[OFFSET_YEAR] > 9999 { 124 dt[OFFSET_YEAR] = int(int16(dt[OFFSET_YEAR] | 0x8000)) 125 } 126 127 dt[OFFSET_MONTH] = ((int(value[1]) >> 7) & 0x1) + ((int(value[2]) & 0x07) << 1) 128 129 dt[OFFSET_DAY] = ((int(value[2]) & 0xF8) >> 3) & 0x1f 130 } else if len(value) < 8 { 131 132 dt[OFFSET_HOUR] = int(value[0]) & 0x1F 133 dt[OFFSET_MINUTE] = ((int(value[0]) >> 5) & 0x07) + ((int(value[1]) & 0x07) << 3) 134 dt[OFFSET_SECOND] = ((int(value[1]) >> 3) & 0x1f) + ((int(value[2]) & 0x01) << 5) 135 dt[OFFSET_MILLISECOND] = ((int(value[2]) >> 1) & 0x7f) + ((int(value[3]) & 0x00ff) << 7) + ((int(value[4]) & 0x1F) << 15) 136 137 if len(value) > 5 { 138 dt[OFFSET_TIMEZONE] = int(Dm_build_1.Dm_build_98(value, 5)) 139 } 140 } else { 141 142 dt[OFFSET_YEAR] = int(Dm_build_1.Dm_build_98(value, 0)) & 0x7FFF 143 if dt[OFFSET_YEAR] > 9999 { 144 dt[OFFSET_YEAR] = int(int16(dt[OFFSET_YEAR] | 0x8000)) 145 } 146 147 dt[OFFSET_MONTH] = ((int(value[1]) >> 7) & 0x1) + ((int(value[2]) & 0x07) << 1) 148 149 dt[OFFSET_DAY] = ((int(value[2]) & 0xF8) >> 3) & 0x1f 150 151 dt[OFFSET_HOUR] = (int(value[3]) & 0x1F) 152 153 dt[OFFSET_MINUTE] = ((int(value[3]) >> 5) & 0x07) + ((int(value[4]) & 0x07) << 3) 154 155 dt[OFFSET_SECOND] = ((int(value[4]) >> 3) & 0x1f) + ((int(value[5]) & 0x01) << 5) 156 157 dt[OFFSET_MILLISECOND] = ((int(value[5]) >> 1) & 0x7f) + ((int(value[6]) & 0x00ff) << 7) + ((int(value[7]) & 0x1F) << 15) 158 159 if len(value) > 8 { 160 dt[OFFSET_TIMEZONE] = int(Dm_build_1.Dm_build_98(value, 8)) 161 } 162 } 163 return dt 164 } 165 166 func dmdtDecodeBdta(value []byte) []int { 167 dt := make([]int, DT_LEN) 168 dt[OFFSET_YEAR] = int(Dm_build_1.Dm_build_98(value, 0)) 169 dt[OFFSET_MONTH] = int(value[2] & 0xFF) 170 dt[OFFSET_DAY] = int(value[3] & 0xFF) 171 dt[OFFSET_HOUR] = int(value[4] & 0xFF) 172 dt[OFFSET_MINUTE] = int(value[5] & 0xFF) 173 dt[OFFSET_SECOND] = int(value[6] & 0xFF) 174 dt[OFFSET_MILLISECOND] = int((value[7] & 0xFF) + (value[8] << 8) + (value[9] << 16)) 175 dt[OFFSET_TIMEZONE] = int(Dm_build_1.Dm_build_98(value, 10)) 176 return dt 177 } 178 179 func dtToStringByOracleFormat(dt []int, oracleFormatPattern string, language int) string { 180 return format(dt, oracleFormatPattern, language) 181 } 182 183 func dtToString(dt []int, dtype int, scale int) string { 184 switch dtype { 185 case DATE: 186 return formatYear(dt[OFFSET_YEAR]) + "-" + format2(dt[OFFSET_MONTH]) + "-" + format2(dt[OFFSET_DAY]) 187 188 case TIME: 189 if scale > 0 { 190 return format2(dt[OFFSET_HOUR]) + ":" + format2(dt[OFFSET_MINUTE]) + ":" + format2(dt[OFFSET_SECOND]) + "." + formatMilliSecond(dt[OFFSET_MILLISECOND], scale) 191 } else { 192 return format2(dt[OFFSET_HOUR]) + ":" + format2(dt[OFFSET_MINUTE]) + ":" + format2(dt[OFFSET_SECOND]) 193 } 194 195 case TIME_TZ: 196 if scale > 0 { 197 return format2(dt[OFFSET_HOUR]) + ":" + format2(dt[OFFSET_MINUTE]) + ":" + format2(dt[OFFSET_SECOND]) + "." + formatMilliSecond(dt[OFFSET_MILLISECOND], scale) + " " + formatTZ(dt[OFFSET_TIMEZONE]) 198 } else { 199 return format2(dt[OFFSET_HOUR]) + ":" + format2(dt[OFFSET_MINUTE]) + ":" + format2(dt[OFFSET_SECOND]) + " " + formatTZ(dt[OFFSET_TIMEZONE]) 200 } 201 202 case DATETIME: 203 if scale > 0 { 204 return formatYear(dt[OFFSET_YEAR]) + "-" + format2(dt[OFFSET_MONTH]) + "-" + format2(dt[OFFSET_DAY]) + " " + format2(dt[OFFSET_HOUR]) + ":" + format2(dt[OFFSET_MINUTE]) + ":" + format2(dt[OFFSET_SECOND]) + "." + formatMilliSecond(dt[OFFSET_MILLISECOND], scale) 205 } else { 206 return formatYear(dt[OFFSET_YEAR]) + "-" + format2(dt[OFFSET_MONTH]) + "-" + format2(dt[OFFSET_DAY]) + " " + format2(dt[OFFSET_HOUR]) + ":" + format2(dt[OFFSET_MINUTE]) + ":" + format2(dt[OFFSET_SECOND]) 207 } 208 209 case DATETIME_TZ: 210 if scale > 0 { 211 return formatYear(dt[OFFSET_YEAR]) + "-" + format2(dt[OFFSET_MONTH]) + "-" + format2(dt[OFFSET_DAY]) + " " + format2(dt[OFFSET_HOUR]) + ":" + format2(dt[OFFSET_MINUTE]) + ":" + format2(dt[OFFSET_SECOND]) + "." + formatMilliSecond(dt[OFFSET_MILLISECOND], scale) + " " + formatTZ(dt[OFFSET_TIMEZONE]) 212 } else { 213 return formatYear(dt[OFFSET_YEAR]) + "-" + format2(dt[OFFSET_MONTH]) + "-" + format2(dt[OFFSET_DAY]) + " " + format2(dt[OFFSET_HOUR]) + ":" + format2(dt[OFFSET_MINUTE]) + ":" + format2(dt[OFFSET_SECOND]) + " " + formatTZ(dt[OFFSET_TIMEZONE]) 214 } 215 } 216 217 return "" 218 } 219 220 func formatYear(value int) string { 221 if value >= 0 { 222 if value < 10 { 223 return "000" + strconv.FormatInt(int64(value), 10) 224 } else if value < 100 { 225 return "00" + strconv.FormatInt(int64(value), 10) 226 } else if value < 1000 { 227 return "0" + strconv.FormatInt(int64(value), 10) 228 } else { 229 return strconv.FormatInt(int64(value), 10) 230 } 231 } else { 232 if value > -10 { 233 return "-000" + strconv.FormatInt(int64(-value), 10) 234 } else if value > -100 { 235 return "-00" + strconv.FormatInt(int64(-value), 10) 236 } else if value > -1000 { 237 return "-0" + strconv.FormatInt(int64(-value), 10) 238 } else { 239 return strconv.FormatInt(int64(-value), 10) 240 } 241 } 242 } 243 244 func format2(value int) string { 245 if value < 10 { 246 return "0" + strconv.FormatInt(int64(value), 10) 247 } else { 248 return strconv.FormatInt(int64(value), 10) 249 } 250 } 251 252 func formatMilliSecond(ms int, prec int) string { 253 var ret string 254 if ms < 10 { 255 ret = "00000" + strconv.FormatInt(int64(ms), 10) 256 } else if ms < 100 { 257 ret = "0000" + strconv.FormatInt(int64(ms), 10) 258 } else if ms < 1000 { 259 ret = "000" + strconv.FormatInt(int64(ms), 10) 260 } else if ms < 10000 { 261 ret = "00" + strconv.FormatInt(int64(ms), 10) 262 } else if ms < 100000 { 263 ret = "0" + strconv.FormatInt(int64(ms), 10) 264 } else { 265 ret = strconv.FormatInt(int64(ms), 10) 266 } 267 268 if prec < 6 { 269 ret = ret[:prec] 270 } 271 return ret 272 } 273 274 func formatTZ(tz int) string { 275 tz_hour := int(math.Abs(float64(tz / 60))) 276 tz_min := int(math.Abs(float64(tz % 60))) 277 278 if tz >= 0 { 279 return "+" + format2(tz_hour) + ":" + format2(tz_min) 280 } else { 281 return "-" + format2(tz_hour) + ":" + format2(tz_min) 282 } 283 } 284 285 func toDTFromTime(x time.Time) []int { 286 hour, min, sec := x.Clock() 287 ts := make([]int, DT_LEN) 288 ts[OFFSET_YEAR] = x.Year() 289 ts[OFFSET_MONTH] = int(x.Month()) 290 ts[OFFSET_DAY] = x.Day() 291 ts[OFFSET_HOUR] = hour 292 ts[OFFSET_MINUTE] = min 293 ts[OFFSET_SECOND] = sec 294 ts[OFFSET_MILLISECOND] = (int)(x.Nanosecond() / 1000) 295 _, tz := x.Zone() 296 ts[OFFSET_TIMEZONE] = tz / 60 297 return ts 298 } 299 300 func toDTFromUnix(sec int64, nsec int64) []int { 301 return toDTFromTime(time.Unix(sec, nsec)) 302 } 303 304 func toDTFromString(s string, dt []int) (dtype int, err error) { 305 defer func() { 306 if p := recover(); p != nil { 307 err = ECGO_INVALID_DATETIME_FORMAT.throw() 308 } 309 }() 310 date_s := "" 311 time_s := "" 312 nanos_s := "" 313 tz_s := "" 314 year := 0 315 month := 0 316 day := 0 317 hour := 0 318 minute := 0 319 second := 0 320 a_nanos := 0 321 firstDash := -1 322 secondDash := -1 323 firstColon := -1 324 secondColon := -1 325 period := -1 326 sign := 0 327 ownTz := INVALID_VALUE 328 dtype = -1 329 330 zeros := "000000000" 331 332 if s != "" && strings.TrimSpace(s) == "" { 333 return 0, ECGO_INVALID_DATETIME_FORMAT.throw() 334 } 335 s = strings.TrimSpace(s) 336 337 if strings.Index(s, "-") == 0 { 338 s = strings.TrimSpace(s[1:]) 339 sign = 1 340 } 341 342 comps := strings.Split(s, " ") 343 344 switch len(comps) { 345 case 3: 346 date_s = comps[0] 347 time_s = comps[1] 348 tz_s = comps[2] 349 dtype = DATETIME_TZ 350 351 case 2: 352 if strings.Index(comps[0], ":") > 0 { 353 time_s = comps[0] 354 tz_s = comps[1] 355 dtype = TIME_TZ 356 } else { 357 date_s = comps[0] 358 time_s = comps[1] 359 dtype = DATETIME 360 } 361 362 case 1: 363 if strings.Index(comps[0], ":") > 0 { 364 time_s = comps[0] 365 dtype = TIME 366 } else { 367 date_s = comps[0] 368 dtype = DATE 369 } 370 371 default: 372 return 0, ECGO_INVALID_DATETIME_FORMAT.throw() 373 } 374 375 if date_s != "" { 376 377 firstDash = strings.Index(date_s, "-") 378 secondDash = strings.Index(date_s[firstDash+1:], "-") 379 380 if firstDash < 0 || secondDash < 0 { 381 firstDash = strings.Index(s, ".") 382 secondDash = strings.Index(date_s[firstDash+1:], ".") 383 } 384 385 if firstDash < 0 || secondDash < 0 { 386 firstDash = strings.Index(s, "/") 387 secondDash = strings.Index(date_s[firstDash+1:], "/") 388 } 389 if secondDash > 0 { 390 secondDash += firstDash + 1 391 } 392 393 if (firstDash > 0) && (secondDash > 0) && (secondDash < len(date_s)-1) { 394 395 if sign == 1 { 396 i, err := strconv.ParseInt(date_s[:firstDash], 10, 32) 397 if err != nil { 398 return 0, ECGO_INVALID_DATETIME_FORMAT.addDetailln(err.Error()).throw() 399 } 400 year = 0 - int(i) - 1900 401 } else { 402 i, err := strconv.ParseInt(date_s[:firstDash], 10, 32) 403 if err != nil { 404 return 0, ECGO_INVALID_DATETIME_FORMAT.addDetailln(err.Error()).throw() 405 } 406 year = int(i) - 1900 407 } 408 409 i, err := strconv.ParseInt(date_s[firstDash+1:secondDash], 10, 32) 410 if err != nil { 411 return 0, ECGO_INVALID_DATETIME_FORMAT.addDetailln(err.Error()).throw() 412 } 413 month = int(i) - 1 414 415 i, err = strconv.ParseInt(date_s[secondDash+1:], 10, 32) 416 if err != nil { 417 return 0, ECGO_INVALID_DATETIME_FORMAT.addDetailln(err.Error()).throw() 418 } 419 day = int(i) 420 421 if !checkDate(year+1900, month+1, day) { 422 return -1, ECGO_INVALID_DATETIME_FORMAT.throw() 423 } 424 } else { 425 return -1, ECGO_INVALID_DATETIME_FORMAT.throw() 426 } 427 } 428 429 if time_s != "" { 430 firstColon = strings.Index(time_s, ":") 431 secondColon = strings.Index(time_s[firstColon+1:], ":") 432 if secondColon > 0 { 433 secondColon += firstColon + 1 434 } 435 436 period = strings.Index(time_s[secondColon+1:], ".") 437 if period > 0 { 438 period += secondColon + 1 439 } 440 441 if (firstColon > 0) && (secondColon > 0) && (secondColon < len(time_s)-1) { 442 i, err := strconv.ParseInt(time_s[:firstColon], 10, 32) 443 if err != nil { 444 return 0, ECGO_INVALID_DATETIME_FORMAT.addDetailln(err.Error()).throw() 445 } 446 hour = int(i) 447 448 i, err = strconv.ParseInt(time_s[firstColon+1:secondColon], 10, 32) 449 if err != nil { 450 return 0, ECGO_INVALID_DATETIME_FORMAT.addDetailln(err.Error()).throw() 451 } 452 minute = int(i) 453 454 if period > 0 && period < len(time_s)-1 { 455 i, err = strconv.ParseInt(time_s[secondColon+1:period], 10, 32) 456 if err != nil { 457 return 0, ECGO_INVALID_DATETIME_FORMAT.addDetailln(err.Error()).throw() 458 } 459 second = int(i) 460 461 nanos_s = time_s[period+1:] 462 if len(nanos_s) > 9 { 463 return -1, ECGO_INVALID_DATETIME_FORMAT.throw() 464 } 465 if !unicode.IsDigit(rune(nanos_s[0])) { 466 return -1, ECGO_INVALID_DATETIME_FORMAT.throw() 467 } 468 nanos_s = nanos_s + zeros[0:9-len(nanos_s)] 469 470 i, err = strconv.ParseInt(nanos_s[:6], 10, 32) 471 if err != nil { 472 return 0, ECGO_INVALID_DATETIME_FORMAT.addDetailln(err.Error()).throw() 473 } 474 a_nanos = int(i) 475 } else if period > 0 { 476 return -1, ECGO_INVALID_DATETIME_FORMAT.throw() 477 } else { 478 i, err = strconv.ParseInt(time_s[secondColon+1:], 10, 32) 479 if err != nil { 480 return 0, ECGO_INVALID_DATETIME_FORMAT.addDetailln(err.Error()).throw() 481 } 482 second = int(i) 483 } 484 485 if hour >= 24 || hour < 0 || minute >= 60 || minute < 0 || second >= 60 || second < 0 { 486 return -1, ECGO_INVALID_DATETIME_FORMAT.throw() 487 } 488 } else { 489 return -1, ECGO_INVALID_DATETIME_FORMAT.throw() 490 } 491 } 492 493 if tz_s != "" { 494 neg := false 495 if strings.Index(tz_s, "-") == 0 { 496 neg = true 497 } 498 499 if strings.Index(tz_s, "-") == 0 || strings.Index(tz_s, "+") == 0 { 500 tz_s = strings.TrimSpace(tz_s[1:]) 501 } 502 503 hm := strings.Split(tz_s, ":") 504 var tzh, tzm int16 = 0, 0 505 switch len(hm) { 506 case 2: 507 s, err := strconv.ParseInt(strings.TrimSpace(hm[0]), 10, 16) 508 if err != nil { 509 return -1, ECGO_INVALID_DATETIME_FORMAT.throw() 510 } 511 tzh = int16(s) 512 513 s, err = strconv.ParseInt(strings.TrimSpace(hm[1]), 10, 16) 514 if err != nil { 515 return -1, ECGO_INVALID_DATETIME_FORMAT.throw() 516 } 517 tzm = int16(s) 518 case 1: 519 s, err := strconv.ParseInt(strings.TrimSpace(hm[0]), 10, 16) 520 if err != nil { 521 return -1, ECGO_INVALID_DATETIME_FORMAT.throw() 522 } 523 tzh = int16(s) 524 default: 525 return -1, ECGO_INVALID_DATETIME_FORMAT.throw() 526 } 527 528 ownTz = int(tzh*60 + tzm) 529 if ownTz < 0 { 530 return -1, ECGO_INVALID_DATETIME_FORMAT.throw() 531 } 532 533 if neg { 534 ownTz *= -1 535 } 536 537 if ownTz <= -13*60 || ownTz > 14*60 { 538 return -1, ECGO_INVALID_DATETIME_FORMAT.throw() 539 } 540 } 541 542 dt[OFFSET_YEAR] = year + 1900 543 dt[OFFSET_MONTH] = month + 1 544 if day == 0 { 545 dt[OFFSET_DAY] = 1 546 } else { 547 dt[OFFSET_DAY] = day 548 } 549 dt[OFFSET_HOUR] = hour 550 dt[OFFSET_MINUTE] = minute 551 dt[OFFSET_SECOND] = second 552 dt[OFFSET_MILLISECOND] = a_nanos 553 dt[OFFSET_TIMEZONE] = int(ownTz) 554 return dtype, nil 555 } 556 557 func transformTZ(dt []int, defaultSrcTz int, destTz int) { 558 srcTz := defaultSrcTz 559 if dt[OFFSET_TIMEZONE] != INVALID_VALUE { 560 srcTz = dt[OFFSET_TIMEZONE] 561 } 562 563 if destTz != srcTz { 564 dt = addMinute(dt, destTz-srcTz) 565 if dt[OFFSET_TIMEZONE] != INVALID_VALUE { 566 dt[OFFSET_TIMEZONE] = destTz 567 } 568 } 569 } 570 571 func encode(dt []int, dtype int, scale int, lTz int) ([]byte, error) { 572 573 if isLocalTimeZone(dtype, scale) && dt[OFFSET_TIMEZONE] != INVALID_VALUE && dt[OFFSET_TIMEZONE] != lTz { 574 transformTZ(dt, dt[OFFSET_TIMEZONE], lTz) 575 } 576 577 if dt[OFFSET_YEAR] < -4712 || dt[OFFSET_YEAR] > 9999 { 578 return nil, ECGO_DATETIME_OVERFLOW.throw() 579 } 580 581 year := dt[OFFSET_YEAR] 582 583 month := dt[OFFSET_MONTH] 584 585 day := dt[OFFSET_DAY] 586 587 hour := dt[OFFSET_HOUR] 588 589 min := dt[OFFSET_MINUTE] 590 591 sec := dt[OFFSET_SECOND] 592 593 msec := dt[OFFSET_MILLISECOND] 594 595 var tz int 596 597 if dt[OFFSET_TIMEZONE] == INVALID_VALUE { 598 tz = lTz 599 } else { 600 tz = dt[OFFSET_TIMEZONE] 601 } 602 603 var ret []byte 604 605 if dtype == DATE { 606 ret = make([]byte, 3) 607 608 ret[0] = (byte)(year & 0xFF) 609 610 if year >= 0 { 611 ret[1] = (byte)((year >> 8) | ((month & 0x01) << 7)) 612 } else { 613 ret[1] = (byte)((year >> 8) & (((month & 0x01) << 7) | 0x7f)) 614 } 615 616 ret[2] = (byte)(((month & 0x0E) >> 1) | (day << 3)) 617 } else if dtype == DATETIME { 618 ret = make([]byte, 8) 619 620 ret[0] = (byte)(year & 0xFF) 621 622 if year >= 0 { 623 ret[1] = (byte)((year >> 8) | ((month & 0x01) << 7)) 624 } else { 625 ret[1] = (byte)((year >> 8) & (((month & 0x01) << 7) | 0x7f)) 626 } 627 628 ret[2] = (byte)(((month & 0x0E) >> 1) | (day << 3)) 629 630 ret[3] = (byte)(hour | ((min & 0x07) << 5)) 631 632 ret[4] = (byte)(((min & 0x38) >> 3) | ((sec & 0x1F) << 3)) 633 634 ret[5] = (byte)(((sec & 0x20) >> 5) | ((msec & 0x7F) << 1)) 635 636 ret[6] = (byte)((msec >> 7) & 0xFF) 637 638 ret[7] = (byte)((msec >> 15) & 0xFF) 639 } else if dtype == DATETIME_TZ { 640 ret = make([]byte, 10) 641 642 ret[0] = (byte)(year & 0xFF) 643 644 if year >= 0 { 645 ret[1] = (byte)((year >> 8) | ((month & 0x01) << 7)) 646 } else { 647 ret[1] = (byte)((year >> 8) & (((month & 0x01) << 7) | 0x7f)) 648 } 649 650 ret[2] = (byte)(((month & 0x0E) >> 1) | (day << 3)) 651 652 ret[3] = (byte)(hour | ((min & 0x07) << 5)) 653 654 ret[4] = (byte)(((min & 0x38) >> 3) | ((sec & 0x1F) << 3)) 655 656 ret[5] = (byte)(((sec & 0x20) >> 5) | ((msec & 0x7F) << 1)) 657 658 ret[6] = (byte)((msec >> 7) & 0xFF) 659 660 ret[7] = (byte)((msec >> 15) & 0xFF) 661 662 Dm_build_1.Dm_build_12(ret, 8, int16(tz)) 663 } else if dtype == TIME { 664 ret = make([]byte, 5) 665 666 ret[0] = (byte)(hour | ((min & 0x07) << 5)) 667 668 ret[1] = (byte)(((min & 0x38) >> 3) | ((sec & 0x1F) << 3)) 669 670 ret[2] = (byte)(((sec & 0x20) >> 5) | ((msec & 0x7F) << 1)) 671 672 ret[3] = (byte)((msec >> 7) & 0xFF) 673 674 ret[4] = (byte)((msec >> 15) & 0xFF) 675 } else if dtype == TIME_TZ { 676 ret = make([]byte, 7) 677 678 ret[0] = (byte)(hour | ((min & 0x07) << 5)) 679 680 ret[1] = (byte)(((min & 0x38) >> 3) | ((sec & 0x1F) << 3)) 681 682 ret[2] = (byte)(((sec & 0x20) >> 5) | ((msec & 0x7F) << 1)) 683 684 ret[3] = (byte)((msec >> 7) & 0xFF) 685 686 ret[4] = (byte)((msec >> 15) & 0xFF) 687 688 Dm_build_1.Dm_build_12(ret, 5, int16(tz)) 689 } 690 691 return ret, nil 692 } 693 694 func checkDate(year int, month int, day int) bool { 695 if year > 9999 || year < -4712 || month > 12 || month < 1 { 696 return false 697 } 698 699 monthDays := getDaysOfMonth(year, month) 700 if day > monthDays || day < 1 { 701 return false 702 } 703 return true 704 } 705 706 func getDaysOfMonth(year int, month int) int { 707 switch month { 708 case 1, 3, 5, 7, 8, 10, 12: 709 return 31 710 case 4, 6, 9, 11: 711 return 30 712 case 2: 713 if isLeapYear(year) { 714 return 29 715 } 716 return 28 717 default: 718 return 0 719 } 720 } 721 722 func isLeapYear(year int) bool { 723 return ((year%4 == 0 && year%100 != 0) || year%400 == 0) 724 } 725 726 func addYear(dt []int, n int) []int { 727 dt[OFFSET_YEAR] += n 728 return dt 729 } 730 731 func addMonth(dt []int, n int) []int { 732 month := dt[OFFSET_MONTH] + n 733 addYearValue := month / 12 734 if month %= 12; month < 1 { 735 month += 12 736 addYearValue-- 737 } 738 739 daysOfMonth := getDaysOfMonth(dt[OFFSET_YEAR], month) 740 if dt[OFFSET_DAY] > daysOfMonth { 741 dt[OFFSET_DAY] = daysOfMonth 742 } 743 744 dt[OFFSET_MONTH] = month 745 addYear(dt, addYearValue) 746 return dt 747 } 748 749 func addDay(dt []int, n int) []int { 750 tmp := dt[OFFSET_DAY] + n 751 monthDays := 0 752 monthDays = getDaysOfMonth(dt[OFFSET_YEAR], dt[OFFSET_MONTH]) 753 for tmp > monthDays || tmp <= 0 { 754 if tmp > monthDays { 755 addMonth(dt, 1) 756 tmp -= monthDays 757 } else { 758 addMonth(dt, -1) 759 tmp += monthDays 760 } 761 } 762 dt[OFFSET_DAY] = tmp 763 return dt 764 } 765 766 func addHour(dt []int, n int) []int { 767 hour := dt[OFFSET_HOUR] + n 768 addDayValue := hour / 24 769 if hour %= 24; hour < 0 { 770 hour += 24 771 addDayValue-- 772 } 773 774 dt[OFFSET_HOUR] = hour 775 addDay(dt, addDayValue) 776 return dt 777 } 778 779 func addMinute(dt []int, n int) []int { 780 minute := dt[OFFSET_MINUTE] + n 781 addHourValue := minute / 60 782 if minute %= 60; minute < 0 { 783 minute += 60 784 addHourValue-- 785 } 786 787 dt[OFFSET_MINUTE] = minute 788 addHour(dt, addHourValue) 789 return dt 790 }