I was wonder what is the maximum length of the timezone settings in PHP? I'm storing the string in a database, and would like to keep the length as short as possible, but i see timezones like "Canada/East-Saskatchewan", which goes beyond our current limit.
If I could just get a list of all the supported timezone string, I can sort them, but they are currently split on to several different pages.
linky: http://www.php.net/manual/en/timezones.php
Edit June 2021 Answer is 64. Why? That's the width of the column used in MySQL to store those timezone name strings.
The zoneinfo database behind those time zone strings just added new prefixes. To America/Argentina/ComodRivadavia, formerly the longest timezone string, they added posix/America/Argentina/ComodRivadavia and right/America/Argentina/ComodRivadavia, both with a length of 38. This is up from 32, the previous longest string.
And here is the complete PHP code to find that:
<?php
$timezone_identifiers = DateTimeZone::listIdentifiers();
$maxlen = 0;
foreach($timezone_identifiers as $id)
{
if(strlen($id) > $maxlen)
$maxlen = strlen($id);
}
echo "Max Length: $maxlen";
/*
Output:
Max Length: 32
*/
?>
The Olson database — available from ftp://ftp.iana.org/tz/releases/ or http://www.iana.org/time-zones (but see also http://www.twinsun.com/tz/tz-link.htm* and http://en.wikipedia.org/wiki/Tz_database) — is the source of these names. The documentation in the file Theory includes a description of how the zone names are formed. This would help you establish how long names can be.
The longest 'current' names are 30 characters (America/Argentina/Buenos_Aires,
America/Argentina/Rio_Gallegos, America/North_Dakota/New_Salem); the longest 'backwards compatibility' name is 32 characters (America/Argentina/ComodRivadavia).
* Note that the TwinSun site has not been updated for some time and has some outdated links (such as suggesting that the Olson database is available from ftp://ftp.elsie.nci.nih.gov — it is now available from IANA instead).
From the manual:
<?php
$timezone_identifiers = DateTimeZone::listIdentifiers();
for ($i=0; $i < 5; $i++) {
echo "$timezone_identifiers[$i]\n";
}
?>
If you are using MySQL with PHP, consider that MySQL already stores Olson timezone names in the "mysql" system database, in a table called "time_zone_name", in a column called "name". One option is to choose the length of your column to match the length that MySQL uses. In MySQL 5.7, the timezone name length is 64 characters. To determine the length in use on your MySQL installation, follow the example below:
mysql> use mysql
Database changed
mysql> describe time_zone_name;
+--------------+------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------------+------------------+------+-----+---------+-------+
| Name | char(64) | NO | PRI | NULL | |
| Time_zone_id | int(10) unsigned | NO | | NULL | |
+--------------+------------------+------+-----+---------+-------+
2 rows in set (0.01 sec)
Related
I'm dealing with the issue of converting a Date column to an ODBC canonical format in my Microsoft SQL Server 2008.
I have the following SQL query in php:
$sql_query = "UPDATE [$connectionInfo[Database]].[dbo].[log_record] SET [lock]='0' WHERE CONVERT [Date] = '".json_encode($value['Date']['date'])."'
Basically, the part '".json_encode($value['Date']['date'])."' works and is printed as '"2017-06-01 00:00:00"'. But it's the [Date] column that's the problem. How can I compare them? It generates the following error:
error: Conversion failed when converting date and/or time from
character string. query: UPDATE [dba_sql].[dbo].[log_record] SET
[lock]='0' WHERE [Date] = '"2017-06-01 00:00:00"'
I attempted the following, but in vain:
$sql_query = "UPDATE [$connectionInfo[Database]].[dbo].[log_record] SET [lock]='0' WHERE CONVERT CONVERT(varchar, Date, 120) = '".json_encode($value['Date']['date'])."'
Get rid of the double quotes, and remove the convert hanging in your code. There is no need to convert the date in your table to a character type for your comparison.
The following is valid: select convert(date,'2017-06-01 00:00:00')
This is not: select convert(date,'"2017-06-01 00:00:00"')
rextester demo: http://rextester.com/NUNAD13593
Also note: The only truly safe formats for date/time literals in SQL Server, at least for datetime and smalldatetime, are: YYYYMMDD and YYYY-MM-DDThh:mm:ss[.nnn]
Reference: Bad habits to kick : mis-handling date / range queries - Aaron Bertrand
For example, if you have a language setting that implicitly sets the dateformat to dmy, then the same input for two different conversions can yield different output, if not an error:
set language 'british';
select toDatatype = 'datetime' ,val = convert(char(10),convert(datetime,'2017-06-01 00:00:00'),120)
union all
select toDatatype = 'date', val = convert(char(10),convert(date,'2017-06-01 00:00:00'),120)
returns:
+------------+------------+
| toDatatype | val |
+------------+------------+
| datetime | 2017-01-06 |
| date | 2017-06-01 |
+------------+------------+
and select convert(datetime,'2017-06-13') would return an error where as select convert(date,'2017-06-13') would return 2017-06-13.
I have the above table: tblCompInfo, the product_id value is not 100% accurate and I need to fix it. I have total of 543847 total row with 25 different company and 12 different products.
now, The URL is 100% accurate and as you can see from the image I have highlighted with RED which means they are wrong and GREEN which is what it should be updated to.
TASK:
I need to update Product_id by parsing through URL and getting the INTEGER and checking it with product table, if its a product, assign the value else assign 0.
SOLUTION:
I got two solution in my head:
1. EXPORT the entire DATA to EXCEL CVS, change it and UPLOAD it to DATABASE. which means my entire week will be working with EXCEL only.
2. Since I have laravel framework: I can make a function in PHP and get the DATA company wise and UPDATE the table in a foreach loop with condition.
PROBLEM:
So, to make my life easy, I made the PHP function with a simple solution and it works BUT I get MEMORY ALLOCATION PROBLEM.
$companyID = ??;
$tblCompInfos = tblCompInfo::where('company_id', '=', $companyID)->get();
foreach($tblCompInfos as $tblCompInfo)
{
$actual_link = $tblCompInfo->url;
$pathlink = parse_url($actual_link, PHP_URL_PATH);
$product_id_from_url = preg_replace("/[^0-9]/", "" , $pathlink);
$FindIfItsInProductTable = Product::find($product_id_from_url);
$real_product_id = $FindIfItsInProductTable == null ? 0 : $product_id_from_url;
DB::table('tblCompInfo')->where('company_id', '=', $companyID)->where('url', '=', $tblCompInfo->url)->update(array(
'product_id' => $real_product_id,
));
echo $actual_link."-".$real_product_id."=".$tblCompInfo->product_id."<br>";
}
if it was a local server, I would have update my PHP.ini with more memory and do the job.
However, I have a LIVE server and it has to be done in the live server and I have no control or power over PHP.ini.
What to do? How can I do it easily that I will not get a memory issue?
Please help if anyone?
Try this :
UPDATE [table_name] SET product_id = CONVERT(SUBSTR(url, LOCATE('products/', url)+9, LOCATE('/compare',url)-LOCATE('products/', url)+9),UNSIGNED INTEGER)
But this will only works if every url field has suffix as /compare
if you use MariaDB you can use REGEXP_REPLACE to do the changes like
UPDATE your_table
SET url = REGEXP_REPLACE(url,'[0-9]+',Product_id)
WHERE Product_id > 0;
sample
MariaDB [your_schema]> SELECT REGEXP_REPLACE('http://example.com/products/12/compare','[0-9]+','99');
+--------------------------------------------------------------------+
| REGEXP_REPLACE('http://example.com/products/12/compare','[0-9]+','99') |
+--------------------------------------------------------------------+
| http://example.com/products/99/compare |
+--------------------------------------------------------------------+
1 row in set (0.00 sec)
MariaDB [your_schema]>
I have a pretty odd idea but it can work.
Look at that query :
SELECT
'http://example.com/products/12/compare' as url,
'http://example.com/products/' as check1,
'http://example.com/termsets/' as check2,
'http://example.com/products/12/compare' REGEXP 'http://example.com/products/' as regexp_check1, -- check 1
SUBSTRING('http://example.com/products/12/compare', LOCATE('http://example.com/products/','http://example.com/products/12/compare')+LENGTH('http://example.com/products/'),1 ) as test1,
SUBSTRING('http://example.com/products/12/compare', LOCATE('http://example.com/products/','http://example.com/products/12/compare')+LENGTH('http://example.com/products/'),1 ) REGEXP "^[0-9]+$" as test1_only_num,
SUBSTRING('http://example.com/products/12/compare', LOCATE('http://example.com/products/','http://example.com/products/12/compare')+LENGTH('http://example.com/products/'),2 ) as test11,
SUBSTRING('http://example.com/products/12/compare', LOCATE('http://example.com/products/','http://example.com/products/12/compare')+LENGTH('http://example.com/products/'),1 ) REGEXP "^[0-9]+$" as test11_only_num,
SUBSTRING('http://example.com/products/12/compare', LOCATE('http://example.com/products/','http://example.com/products/12/compare')+LENGTH('http://example.com/products/'),3 ) as test111,
SUBSTRING('http://example.com/products/12/compare', LOCATE('http://example.com/products/','http://example.com/products/12/compare')+LENGTH('http://example.com/products/'),1 ) REGEXP "^[0-9]+$" as test111_only_num;
Result :
+----------------------------------------+------------------------------+------------------------------+---------------+-------+----------------+--------+-----------------+---------+------------------+
| url | check1 | check2 | regexp_check1 | test1 | test1_only_num | test11 | test11_only_num | test111 | test111_only_num |
+----------------------------------------+------------------------------+------------------------------+---------------+-------+----------------+--------+-----------------+---------+------------------+
| http://example.com/products/12/compare | http://example.com/products/ | http://example.com/termsets/ | 1 | 1 | 1 | 12 | 1 | 12/ | 0 |
+----------------------------------------+------------------------------+------------------------------+---------------+-------+----------------+--------+-----------------+---------+------------------+
Url, check1 and check2 are just to display the variables I'm using. It's a main ID, the query is not usable that way of course.
Logic with check1
You check with a REGEX if check1 is present in your URL. If yes, regexp_check1 is 1, else it's 0.
ONLY if regexp_check1 is 1, then you SUBSTRING your URL to take the part that is located AFTER the check1 sentence. You take the first character AFTER (test1), then the two characters AFTER (test11), the three characters AFTER (test111) etc.. until the max length your ID_PRODUCT can be (6 or 7 for example).
You REGEX the SUBSTR you isolated to check if they are numeric only (test1 is numeric, test11 is numeric only, test111 is not numeric only.
Then you know that the content of test11 is your ID
Then you do the same thing with check2 if regexp_check1 was 0, and with an eventual check3 (which would contain http://www.comadso.dk/products/ for example), and for every beginning you can have.
Maybe my idea is a shitty one, but hey if it's seem dumb but works, it's not dumb !
I have a Laravel5 web application of Business directory.
When I Encrypting a value like
$cryptval = Crypt::encrypt(1);
result = eyJpdiI6IndhaFZFNlhIRDlURzdXanJVMEhBM0E9PSIsInZhbHVlIjoidWF3VzRFZDhyRHltUlwveDdyV0VVWnc9PSIsIm1hYyI6IjE5YjA2YWIyN2Q0MTBlYjdhNDJiNDE5ZjY2OGQ2MDA2NzQ3ZTA4ODc4NzY0ZTIwMjBiMzQxN2RjNmM5ZDg3ZjYifQ==
its giving a long string about 250 length.
Is there any way to limit the length of this string in laravel?
My Client needs to add the URL with encrypted value in a mail function.
eg:
www.example.com/varify/eyJpdiI6IndhaFZFNlhIRDlURzdXanJVMEhBM0E9PSIsInZhbHVlIjoidWF3VzRFZDhyRHltUlwveDdyV0VVWnc9PSIsIm1hYyI6IjE5YjA2YWIyN2Q0MTBlYjdhNDJiNDE5ZjY2OGQ2MDA2NzQ3ZTA4ODc4NzY0ZTIwMjBiMzQxN2RjNmM5ZDg3ZjYifQ==
But the mail function only allow some length of URL :(
One solution is to store the hashed values in a table, and then reference the hash by the auto-incrementing ID of the hash value.
| id | hash | timestamp | random_key |
| 1 | some-hash | 125346164 | 21415 |
| 2 | some-other-hash | 123513515 | 25151 |
So now, instead of using:
www.example.com/verify/some-hash
You can use:
www.example.com/verify/1
The id should really be obfuscated, and not used just as an integer - which is where the timestamp and random_key can help.
$id = 1;
$timestamp = 125346164;
$randomKey = 21415;
$key = base64_encode($timestamp . $randomKey . $id);
echo 'http://www.domain.com/verify/' . $key;
// http://www.domain.com/verify/MTI1MzQ2MTY0MjE0MTUx
All that being said, my recommendation would be to try to work around the limitation put in place by the e-mail delivery platform as URL's can support an address length of around 2000 characters. The example you gave only had a length of 32 and falls well within the lengths acceptable by any modern browser.
Edit: Just generate a uuid using a package like this rather than trying to create your own random id. This will produce a string such as d3d29d70-1d25-11e3-8591-034165a3a613.
I think dont need to store nothing in database, that is a hard work,
In my case a use base64_encode in blase and use base64_decode in controller to show the real value to method and continue the process.
I just faced the same problem. I simply added a column 'hash' in my database table. Then I filled it with a md5(encrypt($model->id))
The md5 value is much shorter, and because it also uses Laravel's crypt, it can't be guessed.
For example, this is my table, which is called example:
--------------------------
| id | en_word | zh_word |
--------------------------
| 1 | Internet| 互联网 |
--------------------------
| 2 | Hello | 你好 |
--------------------------
and so on...
And I tried using this SQL Query:
SELECT * FROM `example` WHERE LENGTH(`zh_word`) = 3
For some reason, it wouldn't give me three, but would give me a lot of single letter characters.
Why is this? Can this be fixed? I tried this out in PhpMyAdmin.
But when I did it with JavaScript:
"互联网".length == 3; // true
And it seems to work fine. So how come it doesn't work?
you should use CHAR_LENGTH instead of LENGTH
LENGTH() returns the length of the string measured in bytes.
CHAR_LENGTH() returns the length of the string measured in characters.
LENGTH returns length in bytes (and chinese is multibyte)
Use CHAR_LENGTH to get length in characters
http://dev.mysql.com/doc/refman/5.0/en/string-functions.html#function_char-length
http://dev.mysql.com/doc/refman/5.0/en/string-functions.html#function_length
I am looking up which exchange services which telephone numbers, from a table of fragmentary numbers that show which exchange services them.
So my table contains, for example:
id |exchcode |exchname |easting|northin|leadin |
-----------------------------------------------------------------
12122 |SNL/UC |SANDAL |43430 |41306 |1924240 |
12123 |SNL/UC |SANDAL |43430 |41306 |1924241 |
881 |SNL/UD |SANDAL |43430 |41306 |1924249 |
2456 |BD/BCC/1 |BRADFORD CABLE |41627 |43262 |192421 |
4313 |NEY/UB |NORMANTON |43847 |42289 |192422 |
12124 |SNL/UC |SANDAL |43430 |41306 |192425 |
9949 |OBE/UB |HORBURY OSSETT |42857 |41971 |192428 |
9987 |OBE/UB |WAKEFIELD |42857 |41971 |1924 |
(sorry, formatting a bit rubbish)
leadin is the leading part of the phone number I have to match (stored as a VARCHAR, not a number)
And I am supplied with a phone number 1924283777 (not real)
how do I query to get the best match from the above table (It should pick exchange id 9949), or do I deal with it in code after I've done the query (php)
tl;dr: variable length for values of leadin column, want best match with a number longer than leadin.
I would think something like
WHERE ? LIKE concat(leadin, '%') order by length(leadin) desc limit 1
(I haven't checked the function names, and I'm not certain that this will work in MYSQL - I'm pretty sure it will work in one of the SQL's I've used).