0

For saving the days of week in a database, I've the existing code :

if (isset($_POST['day7'])){$dayOfWeek = 1;} else { $dayOfWeek = ''; }
if (isset($_POST['day1'])){$dayOfWeek = $dayOfWeek + 2;}
if (isset($_POST['day2'])){$dayOfWeek = $dayOfWeek + 4;}
if (isset($_POST['day3'])){$dayOfWeek = $dayOfWeek + 8;}
if (isset($_POST['day4'])){$dayOfWeek = $dayOfWeek + 16;}
if (isset($_POST['day5'])){$dayOfWeek = $dayOfWeek + 32;}
if (isset($_POST['day6'])){$dayOfWeek = $dayOfWeek + 64;}

For exemple : Monday, Friday, Saturday is : int(98) (2+32+64) bin value for that = 1100010

Other exemple : Sunday, Monday = int(3) (2+1) Bin value = 11

My question is : How to do the reverse in order to get the days of week in : exemple : String(Mon, Fri, Sat) from the int value ?

I can do it with a binary value like 1100010, but I don't understand how to do it when the binary is less than 7 "characters", like 11

<?php
function binToWeekdays($binvalue) {

    $array_week = array();
    $array_week = str_split($binvalue);
    $array_week = array_reverse($array_week);

    $weekdays = '';

    if ($array_week[1] == 1) {
        $weekdays .= 'Mon, ';
    }
    if ($array_week[2] == 1) {
        $weekdays .= 'Tue, ';
    }
    if ($array_week[3] == 1) {
        $weekdays .= 'Wed, ';
    }
    if ($array_week[4] == 1) {
        $weekdays .= 'Thu, ';
    }
    if ($array_week[5] == 1) {
        $weekdays .= 'Fri, ';
    }
    if ($array_week[6] == 1) {
        $weekdays .= 'Sat, ';
    }
    if ($array_week[0] == 1) {
        $weekdays .= 'Sun';
    }

    return $weekdays;

}

echo binToWeekdays('1100010');

?>

Returns : Mon, Fri, Sat,

Thanks for your help

ADyson
  • 57,178
  • 14
  • 51
  • 63
Joel
  • 192
  • 12
  • 1
    Dare I ask why you don't just store ints like 0-6 or something – ADyson May 12 '22 at 15:30
  • @ADyson It's not my choice to do it like that, I've to adapt my code to an existing system. / database... – Joel May 12 '22 at 15:31
  • Ok. `I can do it with a binary value like 1100010`...show us how you'd do it then, and we can maybe help you adapt. – ADyson May 12 '22 at 15:33
  • 1
    Just to be clear, are you saying you're storing selections of days in binary notation in the database? And you are now trying to reverse binary `11` which is 3 in decimal to Sunday (1) and Monday (2)? – waterloomatt May 12 '22 at 15:36
  • @ADyson I've edited my question. waterloomatt : The INT value is stored in the database. I thought the easiest way was to convert to binary, but I might be wrong... – Joel May 12 '22 at 15:43
  • Sorry it's a bit unclear from your last comment. Are you saying the value `1100010` is stored in the database for example? – ADyson May 12 '22 at 15:44
  • @ADyson No, it's the int value (98 in the exemple) – Joel May 12 '22 at 15:45
  • Your code says 1100010 is Mon, Fri, Sun, not Mon, Fri Sat. Which is the correct interpretation? It would depend whether you read the values left-to-right or right-to-left (starting with Sunday in each case). https://3v4l.org/ioNJ7 . In fact your question text later states this, so I'm assuming the "Monday, Friday, Saturday" earlier in the text is a typo? – ADyson May 12 '22 at 15:51
  • @ADyson I've edited the question, I added array_reverse. Sorry, I've been looking for a solution for a while and I'm a bit lost trying to find it. :S – Joel May 12 '22 at 15:59
  • No worries. See my answer below – ADyson May 12 '22 at 16:04
  • @ADyson Sorry about that, my bad. Thanks for your help – Joel May 12 '22 at 16:26
  • Does this answer your question? [How to implement a bitmask in php?](https://stackoverflow.com/questions/11880360/how-to-implement-a-bitmask-in-php) – CBroe May 13 '22 at 08:00

4 Answers4

3

Picking up the accepted solution from Matthias Radde (which I liked because of the use of binary operators), but now able to define the map of a weekdays bit position...

function binToWeekdays($binvalue, $map) {
    $decvalue = bindec($binvalue);
    $weekdays = [];
    
    foreach($map as $day => $exp){
        if (($decvalue & (1 << $exp)) != 0) {
            $weekdays[] = $day;
        }
    }
    return implode(', ', $weekdays);
}

// with sunday = 0
$map = [
    'Sun' => 0,'Mon' => 1,'Tue' => 2,
    'Wed' => 3,'Thu' => 4,'Fri' => 5,'Sat' => 6,
];  

echo binToWeekdays('1100010', $map) . "<br />\n"; // => Mon, Fri, Sat
echo binToWeekdays('11', $map) . "<br />\n"; // =>  Mon, Sun

// with monday = 0
$map = [
    'Mon' => 0,'Tue' => 1,'Wed' => 2,
    'Thu' => 3,'Fri' => 4,'Sat' => 5,'Sun' => 6,
];  

echo binToWeekdays('1100010', $map) . "<br />\n"; // => Tue, Sat, Sun
echo binToWeekdays('11', $map) . "<br />\n"; // =>  Mon, Tue
Honk der Hase
  • 2,459
  • 1
  • 14
  • 26
2

other idea (instead of padding the string with zeros):

convert the binary value to an integer and use the binary &-operator for checking if a day is selected:

function binToWeekdays($binvalue) {
  $decvalue = bindec($binvalue);
  $weekdays = array();
  if($decvalue & 1 << 1){
    $weekdays[] = 'Mon';
  }
  if($decvalue & 1 << 2){
    $weekdays[] = 'Tue';
  }
  if($decvalue & 1 << 3){
    $weekdays[] = 'Wed';
  }
  if($decvalue & 1 << 4){
    $weekdays[] = 'Thu';
  }
  if($decvalue & 1 << 5){
    $weekdays[] = 'Fri';
  }
  if($decvalue & 1 << 6){
    $weekdays[] = 'Sat';
  }
  if($decvalue & 1 << 0){
    $weekdays[] = 'Sun';
  }
  return implode(', ', $weekdays);
}

echo binToWeekdays('1100010') . "<br />\n"; // => Mon, Fri, Sat
echo binToWeekdays('11') . "<br />\n"; // =>  Mon, Sun

In addition I have used an array and imploded this before returning to prevent a trailing comma if there is no sunday selected.

Matthias Radde
  • 161
  • 1
  • 3
  • 8
  • This answer is the one that best corresponds to my request. Thank you all for your help. I really appreciate it, and I learned new things in PHP. There is just a typo here I think : binToWeekdays 2 (' – Joel May 12 '22 at 16:30
  • typo corrected/removed - was a remnant of different versions I've tried :-) – Matthias Radde May 13 '22 at 03:41
0

How about "str_pad" ? If the binary is less than 7 "characters",

str_pad(1,7,"0",STR_PAD_LEFT)
Li Yong
  • 16
  • 5
0

You can simply pad the string with zeros:

function binToWeekdays($binvalue) {

    $binvalue = str_pad($binvalue, 7, "0", STR_PAD_LEFT);
    $array_week = array_reverse(str_split($binvalue));

    $weekdays = '';

    if ($array_week[1] == 1) {
        $weekdays .= 'Mon, ';
    }
    if ($array_week[2] == 1) {
        $weekdays .= 'Tue, ';
    }
    if ($array_week[3] == 1) {
        $weekdays .= 'Wed, ';
    }
    if ($array_week[4] == 1) {
        $weekdays .= 'Thu, ';
    }
    if ($array_week[5] == 1) {
        $weekdays .= 'Fri, ';
    }
    if ($array_week[6] == 1) {
        $weekdays .= 'Sat, ';
    }
    if ($array_week[0] == 1) {
        $weekdays .= 'Sun';
    }

    return $weekdays;

}

echo binToWeekdays('11');

This outputs:

Mon, Sun

Live demo: https://3v4l.org/pSl8I

Documentation: https://www.php.net/manual/en/function.str-pad.php

ADyson
  • 57,178
  • 14
  • 51
  • 63