according to php.net date('m') should should 01 but i'm getting 1 instead
dirloc = date('Y') . "/" . date('m') . "/" . $word_id . "/";
Install PHPUnit. Run the following UnitTest:
// make sure PHPUnit is included
class DateTest extends PHPUnit_Framework_TestCase
{
public function setup()
{
date_default_timezone_set('UTC');
}
public function getDates()
{
return array(
array('01', 'Jan'),
array('02', 'Feb'),
array('03', 'Mar'),
array('04', 'Apr'),
array('05', 'May'),
array('06', 'Jun'),
array('07', 'Jul'),
array('08', 'Aug'),
array('09', 'Sep')
);
}
/**
* #dataProvider getDates
*/
public function testDateReturnsMonthWithLeadingZero($expected, $month)
{
$this->assertSame($expected, date('m', strtotime($month)));
}
}
If the test fails with any of the given test dates, collect your PHP version and Operating system and file a bug with the PHP bugtracker. If the test passes with all the test dates, you are doing something else wrong.
Related
The function below should return the next working day. It takes into account holidays and weekends.
The problem is the weird behaviour at the end (see image below code)
class test{
private static $i;
static function getNextWorkingDay(DateTimeInterface $dateTime) {
self::$i++;
dump("Iteration n°: ".self::$i. " Date: ".$dateTime->format('d/m/Y'));
$dateTime = (new DateTime())->setTimestamp($dateTime->getTimestamp());
if (self::isWeekend($dateTime)) {
dump("Iteration n°: ".self::$i." Weekend");
self::getNextWorkingDay($dateTime->modify('next monday'));
}
if (self::isNotWorkable($dateTime)) {
dump("Iteration n°: ".self::$i." Not workable");
self::getNextWorkingDay($dateTime->modify('next day'));
}
dump("Iteration n°: ".self::$i. " This date should be returned and end the function: ".$dateTime->format('d/m/Y'));
return $dateTime;
}
}
Testing with date = 2020-05-01
I expect 2020-05-04 but it returns 2020-05-02
I'm kind of new to Drupal 8 development and object-oriented PHP in general. I've been trying to make a simple custom block module, which includes a service with simple dependency injection. However, I can't seem to figure out why the construct method does not receive an appropriate parameter - been staring at the code for hours. My code:
event_countdown.services.yml
services:
event_countdown.date_calculator:
class: Drupal\event_countdown\DateCalculator
event_countdown.routing.yml
event_countdown.content:
defaults:
_title: 'Event Countdown'
requirements:
_permission: 'access content'
options:
no_cache: 'TRUE'
src/DateCalculator.php
<?php
namespace Drupal\event_countdown;
class DateCalculator {
// forms the block's output based on given date
public function daysUntilEventStarts($date) {
// get difference in days between now and the given date
$difference = $this->getDifferenceInDaysFromCurrentDate($date);
// if event date is in the future
if($difference >= 1) {
return "Days left until the event starts: " . $difference;
// if event date and current date are on the same day
} else if($difference == 0) {
return "The event is in progress.";
// if event date is in the past
} else {
return "The event has already ended.";
}
}
// calculates difference in days between now and given date
public function getDifferenceInDaysFromCurrentDate($date) {
// current time
$now = time();
// event datetime field converted to timestamp
$event_date = strtotime($date);
// timestamp difference
$difference = $event_date - $now;
// timestamp difference rounded down to days
return round($difference / (60 * 60 * 24));
}
}
src/Plugin/Block/EventCountdownBlock.php
<?php
namespace Drupal\event_countdown\Plugin\Block;
use Drupal\Core\Block\BlockBase;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\event_countdown\DateCalculator;
/**
* Provides an event countdown block.
*
* #Block(
* id = "event_countdown_block",
* admin_label = #Translation("Event countdown block"),
* category = #Translation("Event countdown block"),
* )
*/
class EventCountdownBlock extends BlockBase {
protected $dateCalculator;
public function __construct(DateCalculator $dateCalculator) {
$this->dateCalculator = $dateCalculator;
}
public static function create(ContainerInterface $container) {
return new static($container->get('event_countdown.date_calculator'));
}
public function build() {
// get current node based on route
$node = \Drupal::routeMatch()->getParameter('node');
//check whether node type equals 'event' - if it does, get text output, otherwise display an error message
if($node->getType() == "event") {
// get datetime value from node
$date = $node->field_event_date->value;
// call service method to calculate difference in days
$output = $this->dateCalculator->daysUntilEventStarts($date);
} else {
// display error
$output = "Woops! This block is intended only for event pages.";
}
return array(
// output
'#markup' => $output,
// prevent block caching
'#cache' => [
'max-age' => 0,
],
);
}
}
The error I get in Drupal logs is:
Recoverable fatal error: Argument 1 passed to Drupal\event_countdown\Plugin\Block\EventCountdownBlock::__construct() must be an instance of Drupal\event_countdown\DateCalculator, array given, called in D:\drupal8\devdesktop\drupal-8.5.1\core\lib\Drupal\Core\Plugin\Factory\ContainerFactory.php on line 25 and defined in Drupal\event_countdown\Plugin\Block\EventCountdownBlock->__construct() (line 24 of D:\drupal8\devdesktop\drupal-8.5.1\modules\custom\event_countdown\src\Plugin\Block\EventCountdownBlock.php)#0 D:\drupal8\devdesktop\drupal-8.5.1\core\includes\bootstrap.inc(582):_drupal_error_handler_real(4096, 'Argument 1 pass...', 'D:\\drupal8\\devd...', 24, Array) #1 [...]
I would appreciate any sort of help. Thank you!
Found the solution at https://drupal.stackexchange.com/questions/260187/creating-a-simple-drupal-8-custom-service-argument-should-be-an-instance-of-a. Had to implement ContainerFactoryPluginInterface due to plugins not being container-aware.
I am trying to unit test a function that calls another function that uses the storage facade. When I run the function in phpunit, it returns the error, "Error: Class 'Storage' not found." How can I run the function either without an error or defaulting the second function to return true?
Part of the code I am trying to test.
public function newMaterial($fileType, $groupId, $categoryId, $fileName, $file, $open, $close) {
$material = new Mat;
if (!$this->save($fileType, $file, $material)) {
return false;
}
}
This is the section of code that is causing the error.
protected function save($fileType, $file, Mat $material) {
//generate random name
do {
$key = str_random(32);
//check if exist
} while (Storage::exists($path . $key . '.' . $ext));
return true;
}
This is not all of my code, just the parts that are causing an issue.
In my test I am only calling the newMaterial Function and it returns the error.
I'm a complete beginner so sorry if the way I word this is confusing.
I'm working on my online computer science course right now and we're practising functions. What we're supposed to do is set three sentences to output three different variables inside the sentence
x is y years old and is z
Here's what I mean:
Obama is 50 years old and is president of the United States.
Bill Gates is 60 years old and is Founder of Microsoft.
Jacob is 20 years old and is a student.
This is the code that I currently have:
<?php
function displayStory($name) {
}
function displayAge($age) {
}
function displayJob($job) {
echo $name . " is " . $age . " and is " . $job . ".<br />";
}
displayStory("Obama");
displayAge("50");
displayJob("the President of The United States");
displayStory("Bill Gates");
displayAge("60");
displayJob("the founder of Microsoft");
displayStory("Jacob");
displayAge("20");
displayJob("a student");
?>
I'm sure there's an easier way to complete this and I know other ways to complete this, but we're supposed to use the function DisplayX to complete this.
Thank you in advance :)
What you are looking for is user-defined functions.
A function is basicly a set of instructions, these instructions are generalized with a name. To create one single function, you use the function keyword followed by a space and the name of the function.
In this case, this functionality you need could be achieved by just one function. You can name it something like displayInformation.
The function is gonna need 3 parameters, which are the 3 things you are wanting to display. The name, the age and the job of the person. Parameters should be defined in ( )'s as variables which comes after the function name.
To create this function, it looks something like this:
function displayInformation($name, $age, $job) {
}
The context of the function can now simply be the echo'ing of the data like you did in one of your functions.
echo $name . " is " . $age . " and is " . $job . ".<br />";
The final result of this code would be:
<?php
function displayInformation($name, $age, $job) {
echo $name . " is " . $age . " and is " . $job . ".<br />"
}
displayInformation("Obama", 50, "president of the United States");
displayInformation("Bill Gates", 60, "Founder of Microsoft");
displayInformation("Jacob", 20, "a student");
For more information on user-defined functions, you can read the documentation.
Function design
As for personal preference, best practices and this specific case, you can design your function in another way.
When using PHP functions, it is always going to return a value. This can be a number, some text, a object, you name it.
You could remove the functionality of the function to already "display" the personal information, and just make it return the personal information as a string. This could be done by the return keyword like this:
function getInformation($name, $age, $job) {
return $name . " is " . $age . " and is " . $job . ".<br />"
}
Now you only have to use echo to display the information.
echo getInformation("Obama", 50, "president of the United States");
echo getInformation("Bill Gates", 60, "Founder of Microsoft");
echo getInformation("Jacob", 20, "a student");
More information about returning values can be found here.
If you want to just use a function then you can simplify your function to the following:
function display($name, $age, $job) {
echo $name . " is " . $age . " and is " . $job . ".<br />"
}
display("Obama", 50, "president of the United States");
display("Bill Gates", 60, "Founder of Microsoft");
display("Jacob", 20, "a student");
This will echo out:
Obama is 50 years old and is president of the United States
Bill Gates is 60 years old and is Founder of Microsoft
Jacob is 20 years old and is a student
However you should look at creating classes which are easier to maintain in the long run.
class personInformation {
public $name;
public $age;
public $job;
public function __construct($name, $age, $job) {
$this->name = $name;
$this->age= $age;
$this->job= $job;
}
public function display() {
return $this->name . ' is ' . $this->age . ' and is ' . $this->job . '.<br />';
}
}
Then using this class you can do:
/* Start a new instance of the class */
$obama = new personInformation("Obama", 50, "president of the United States");
$bill = new personInformation("Bill Gates", 60, "Founder of Microsoft");
$jacob = new personInformation("Jacob", 20, "a student");
/* Display the sentences */
echo $obama->display();
echo $bill->display();
echo $jacob->display();
the __construct function is the same as setting each value seperately however it does it when you call a new instance of the class. So rather doing this:
$obama = new personInformation();
$obama->name = "obama";
$obama->age= 50;
$obama->job= "president of the United States";
You create the __construct function however note that you must fill in all the information in the __construct else it will error so you cannot do:
$obama = new personInformation("Obama", 50);
You can add further functions to the class for example:
public function hello() {
return $this->name . ' says hello. <br />';
}
If you don't recognise what's below, fair enough. But some topics to Google and read about are:
PHP variable scope
Object Orientated Programming
So my solution is that you generate a class which handles all the data for the chosen person in an object orientated fashion:
class sentence {
private $name;
private $age;
private $job;
//this is the sentence string that will be
//populated with your data, currently given a default value.
public $output = $this->name . " is " . $this->age . " and is " . $this->job . "!";
/***
Within the class you can create methods which is another
name for functions.
***/
public function setName($name){
$this->name = $name;
}
public function setAge($age){
$this->age = (int)$age; //forces to integer type.
}
public function setJob($job){
//you can fill this one in.
}
} //close class.
So that is the class, how do you use it, well you first create the class as so:
$one = new sentence();
And then add data to it using the functions we set above to save the data parts to the corresponding values.
$one->setAge("50");
$one->setName("george");
And then display the output as follows, note that calling a variable inside a class, rather than a method, means you do not use brackets. So:
//output
print $sentence->output;
This will output
George is 50 and is !
Classes are typcally built in PHP include files and not usually in the file they are usedin.
I'm writing my first PHP app that has to directly deal with dates, and thus to directly deal with the fact that PHP and MySQL have different date formats.
My question is: what's the most elegant way to manage this difference?
I have the following two functions to manage the difference using php:
function mysql_date($php_date) {
return date( 'Y-m-d H:i:s', $php_date );
}
function php_date($mysql_date) {
$val = explode(" ",$mysql_date);
$date = explode("-",$val[0]);
$time = explode(":",$val[1]);
return mktime($time[0],$time[1],$time[2],$date[1],$date[2],$date[0]);
}
is there a simpler way to manage this directly within my SQL queries?
Or could you suggest any other more elegant way to manage this?
Since (around) PHP 5.2, PHP has had a built in class/object for dealing with Dates and Times, called DateTime. In a void, it's always better to use a built-in than to wrangle with the messy details yourself.
The DateTime constructor (or the date_create function) accepts a date in any format understood by strToTime. All you need to know about strToTime is it's magic voodoo that will correctly recognize a date in almost any string format. When I first encountered strToTime I had the same internal reaction you're having now ("that's bullshit/seems unreliable"). It's not. It Just Works in a way that your own fragile understanding of dates never will (and if you think you understand dates, you don't. Trust Me.)
So, pull the information from MySQL as a Date/Time string, and immediately create a PHP date Object. Use the date_format method (with some handy constants) when/if you need the date again as a string.
You can replace php_date with strtotime.
$php = strtotime($mysql);
The MySQL equivalent would be UNIX_TIMESTAMP.
Though, if you want to handle formatting in SQL, try MySQL's DATE_FORMAT.
Store everything in the database in a datetime field in UTC. For PHP manipulation, use the PEAR Date library. I'm not a big PEAR user, but this library is fantastic and will handle all of annoying date conversion issues that you should not be spending your time worrying about.
I would recommend you keep everything in mysql format until you need to display it to the user, then use strtotime() to get a unix timestamp and date() to format it.
If you throw in some Hungarian Notation it's even harder to go wrong:
$ymdDateAdded = date('Y-m-d');
$timeDateAdded = strtotime($ymdDateAdded);
$userDateadded = date('j F Y', $timeDateAdded);
I think it would be a better ideea to store unix timestamps in the DB field. When you need to display dates to human language, you can always use php's date() function. For everything else, just use the numeric timestamp.
You could make a small date object which simply converts the date as you need it
$Date_p = new MagicDate($php_date);
$Date_m = new MagicDate($mysql_date);
The $Date_p and $Date_m are just showing that you can seed the object anyway you need to. When you want a mysql date you would have code like. Realistically it would be something pretty generic like $Date.
$query = "UPDATE SET Date='".$Date_p->toMysql()."' "...
and vice versa when you need the opposite. You can use the functions you've already created. Just add a "sniffer" in the construct method like:
public function __construct($date)
{
$phpdate = strtotime($date);
if($phpdate)
{
$this->phpdate = $phpdate;
$this->mysqldate = $this->mysql_date($phpdate);
}
else
{
$this->phpdate = $this->php_date($phpdate);
$this->mysqldate = $phpdate;
}
}
Throw some error handling in to catch the things that go bad. Add the getter for the two dates. And it's a set it and forget it situation. Just pull the right date out when you need it.
There could be some optimizations, but this is to just show you how it could work.
It is best way to save time and date as unix timestamp rather than other formats.
I have created a class to handle date and time in php. Its easy to use and very very useful
<?php
define("NEW_LINE", "</BR>");
class scTimestamp
{
private $timestamp;
private $year;
private $month;
private $day;
private $hour;
private $minute;
private $second;
public function __construct()
{
register_shutdown_function(array($this,'__destruct'));
$this->setTimestamp($_SERVER['REQUEST_TIME']);
}
public function __destruct()
{
unset($this->timestamp);
unset($this->year);
unset($this->month);
unset($this->day);
unset($this->hour);
unset($this->minute);
unset($this->second);
}
private function rebuildTimestampFromDate()
{
$this->timestamp=mktime($this->hour,$this->minute,$this->second,$this->month,$this->day,$this->year);
}
private function rebuildDateFromTimestamp()
{
$this->day=date('j',$this->timestamp);
$this->month=date('n',$this->timestamp);
$this->year=date('Y',$this->timestamp);
$this->hour=date('g',$this->timestamp);
$this->minute=date('G',$this->timestamp);
$this->second=date('s',$this->timestamp);
}
public function setTimestamp($tempTimestamp)
{
$this->timestamp=$tempTimestamp;
$this->rebuildDateFromTimestamp();
}
public function getTimestamp()
{
return $this->timestamp;
}
public function setYear($tempYear)
{
$this->year = $tempYear;
$this->rebuildTimestampFromDate();
}
public function getYear()
{
return $this->year;
}
public function setMonth($tempMonth)
{
$this->month = $tempMonth;
$this->rebuildTimestampFromDate();
}
public function getMonth()
{
return $this->month;
}
public function setDay($tempDay)
{
$this->day=$tempDay;
$this->rebuildTimestampFromDate();
}
public function getDay()
{
return $this->day;
}
public function setHour($tempHour)
{
$this->hour = $tempHour;
$this->rebuildTimestampFromDate();
}
public function getHour()
{
return $this->hour;
}
public function setMinute($tempMinute)
{
$this->minute = $tempMinute;
$this->rebuildTimestampFromDate();
}
public function getMinute()
{
return $this->minute;
}
public function setSecond($tempSecond)
{
$this->second = $tempSecond;
$this->rebuildTimestampFromDate();
}
public function getSecond()
{
return $this->second;
}
public function getDateDifferenceFromNow()
{
return $this->getDateDifferenceFrom($_SERVER['REQUEST_TIME']);
}
public function getDateDifferenceFrom($fromDate)
{
$return="";
$sec=" Second";
$min=" Minute";
$hrs=" Hour";
$before=" Before";
$difference=$fromDate-$this->getTimestamp();
if($difference<0)
$return.="In the Future";
else if($difference<60)
{
if($difference>1)
$sec.="s";
$return.= $difference.$sec.$before;
}
else if($difference<3600)
{
$difference=intval($difference/60);
if($difference>1)
$min.="s";
$return.=$difference.$min.$before;
}
else if($difference<86400)
{
$difference=intval($difference/3600);
if($difference>1)
$hrs.="s";
$return= $difference.$hrs.$before;
}
else if($difference<604800)
{
$return.= date("l g:i a",$this->getTimestamp());
}
else if($difference<28512000)
{
$return.= date("F j",$this->getTimestamp());
}
else
{
$return.= date("F j, Y, g:i a",$this->getTimestamp());
}
return $return;
}
public function getDateAsString()
{
return date("F j, Y",$this->getTimestamp());
}
public function getDateTimeAsString()
{
return date("F j, Y, g:i a",$this->getTimestamp());
}
public function __toString()
{
$return = NEW_LINE."^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^";
$return.= NEW_LINE." ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^".NEW_LINE;
$return.= NEW_LINE."## Timestamp: ".$this->getTimestamp()." ##".NEW_LINE;
$return.= NEW_LINE."## Date: ".$this->getDateTimeAsString()." ##".NEW_LINE;
$return.= NEW_LINE." ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^".NEW_LINE;
return $return;
}
}
?>
once it is included it can be used as follow
include_once("scTimestamp.php");
$test=new scTimestamp();
echo $test->getDateAsString();
$test->setTimestamp(1210203200);
echo $test->getDateDifferenceFromNow();
echo $test;
$test->setTimestamp(121020320022);
echo $test->getYear();
echo $test;
And the result would like this.
June 26, 2015May 7, 2008, 11:33 pm
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
## Timestamp: 1210203200 ##
## Date: May 7, 2008, 11:33 pm ##
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
5804
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
## Timestamp: 121020320022 ##
## Date: December 25, 5804, 3:33 am ##
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
This class can be used as per needs